0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- LegalizeVectorOps.cpp - Implement SelectionDAG::LegalizeVectors ---===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // This file implements the SelectionDAG::LegalizeVectors method.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 // The vector legalizer looks for vector operations which might need to be
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 // scalarized and legalizes them. This is a separate step from Legalize because
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 // scalarizing can introduce illegal types. For example, suppose we have an
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 // ISD::SDIV of type v2i64 on x86-32. The type is legal (for example, addition
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 // on a v2i64 is legal), but ISD::SDIV isn't legal, so we have to unroll the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 // operation, which introduces nodes with the illegal type i64 which must be
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 // expanded. Similarly, suppose we have an ISD::SRA of type v16i8 on PowerPC;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 // the operation must be unrolled, which introduces nodes with the illegal
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 // type i8 which must be promoted.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 // This does not legalize vector manipulations like ISD::BUILD_VECTOR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 // or operations that happen to take a vector which are custom-lowered;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 // the legalization for such operations never produces nodes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 // with illegal types, so it's okay to put off legalizing them until
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 // SelectionDAG::Legalize runs.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
30 #include "llvm/CodeGen/SelectionDAG.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31 #include "llvm/Target/TargetLowering.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 namespace {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35 class VectorLegalizer {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 SelectionDAG& DAG;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37 const TargetLowering &TLI;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 bool Changed; // Keep track of whether anything changed
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39
|
77
|
40 /// For nodes that are of legal width, and that have more than one use, this
|
|
41 /// map indicates what regularized operand to use. This allows us to avoid
|
|
42 /// legalizing the same thing more than once.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 SmallDenseMap<SDValue, SDValue, 64> LegalizedNodes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44
|
77
|
45 /// \brief Adds a node to the translation cache.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 void AddLegalizedOperand(SDValue From, SDValue To) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 LegalizedNodes.insert(std::make_pair(From, To));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 // If someone requests legalization of the new node, return itself.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 if (From != To)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50 LegalizedNodes.insert(std::make_pair(To, To));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52
|
77
|
53 /// \brief Legalizes the given node.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54 SDValue LegalizeOp(SDValue Op);
|
77
|
55
|
|
56 /// \brief Assuming the node is legal, "legalize" the results.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 SDValue TranslateLegalizeResults(SDValue Op, SDValue Result);
|
77
|
58
|
|
59 /// \brief Implements unrolling a VSETCC.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 SDValue UnrollVSETCC(SDValue Op);
|
77
|
61
|
|
62 /// \brief Implement expand-based legalization of vector operations.
|
|
63 ///
|
|
64 /// This is just a high-level routine to dispatch to specific code paths for
|
|
65 /// operations to legalize them.
|
|
66 SDValue Expand(SDValue Op);
|
|
67
|
|
68 /// \brief Implements expansion for FNEG; falls back to UnrollVectorOp if
|
|
69 /// FSUB isn't legal.
|
|
70 ///
|
|
71 /// Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if
|
|
72 /// SINT_TO_FLOAT and SHR on vectors isn't legal.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
73 SDValue ExpandUINT_TO_FLOAT(SDValue Op);
|
77
|
74
|
|
75 /// \brief Implement expansion for SIGN_EXTEND_INREG using SRL and SRA.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
76 SDValue ExpandSEXTINREG(SDValue Op);
|
77
|
77
|
|
78 /// \brief Implement expansion for ANY_EXTEND_VECTOR_INREG.
|
|
79 ///
|
|
80 /// Shuffles the low lanes of the operand into place and bitcasts to the proper
|
|
81 /// type. The contents of the bits in the extended part of each element are
|
|
82 /// undef.
|
|
83 SDValue ExpandANY_EXTEND_VECTOR_INREG(SDValue Op);
|
|
84
|
|
85 /// \brief Implement expansion for SIGN_EXTEND_VECTOR_INREG.
|
|
86 ///
|
|
87 /// Shuffles the low lanes of the operand into place, bitcasts to the proper
|
|
88 /// type, then shifts left and arithmetic shifts right to introduce a sign
|
|
89 /// extension.
|
|
90 SDValue ExpandSIGN_EXTEND_VECTOR_INREG(SDValue Op);
|
|
91
|
|
92 /// \brief Implement expansion for ZERO_EXTEND_VECTOR_INREG.
|
|
93 ///
|
|
94 /// Shuffles the low lanes of the operand into place and blends zeros into
|
|
95 /// the remaining lanes, finally bitcasting to the proper type.
|
|
96 SDValue ExpandZERO_EXTEND_VECTOR_INREG(SDValue Op);
|
|
97
|
|
98 /// \brief Expand bswap of vectors into a shuffle if legal.
|
|
99 SDValue ExpandBSWAP(SDValue Op);
|
|
100
|
|
101 /// \brief Implement vselect in terms of XOR, AND, OR when blend is not
|
|
102 /// supported by the target.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 SDValue ExpandVSELECT(SDValue Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 SDValue ExpandSELECT(SDValue Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 SDValue ExpandLoad(SDValue Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 SDValue ExpandStore(SDValue Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 SDValue ExpandFNEG(SDValue Op);
|
100
|
108 SDValue ExpandBITREVERSE(SDValue Op);
|
120
|
109 SDValue ExpandCTLZ(SDValue Op);
|
|
110 SDValue ExpandCTTZ_ZERO_UNDEF(SDValue Op);
|
77
|
111
|
|
112 /// \brief Implements vector promotion.
|
|
113 ///
|
|
114 /// This is essentially just bitcasting the operands to a different type and
|
|
115 /// bitcasting the result back to the original type.
|
|
116 SDValue Promote(SDValue Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117
|
77
|
118 /// \brief Implements [SU]INT_TO_FP vector promotion.
|
|
119 ///
|
|
120 /// This is a [zs]ext of the input operand to the next size up.
|
|
121 SDValue PromoteINT_TO_FP(SDValue Op);
|
|
122
|
|
123 /// \brief Implements FP_TO_[SU]INT vector promotion of the result type.
|
|
124 ///
|
|
125 /// It is promoted to the next size up integer type. The result is then
|
|
126 /// truncated back to the original type.
|
|
127 SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned);
|
|
128
|
|
129 public:
|
|
130 /// \brief Begin legalizer the vector operations in the DAG.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 bool Run();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132 VectorLegalizer(SelectionDAG& dag) :
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
133 DAG(dag), TLI(dag.getTargetLoweringInfo()), Changed(false) {}
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
134 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 bool VectorLegalizer::Run() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137 // Before we start legalizing vector nodes, check if there are any vectors.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 bool HasVectors = false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
77
|
140 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 // Check if the values of the nodes contain vectors. We don't need to check
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 // the operands because we are going to check their values at some point.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143 for (SDNode::value_iterator J = I->value_begin(), E = I->value_end();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144 J != E; ++J)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 HasVectors |= J->isVector();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 // If we found a vector node we can start the legalization.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 if (HasVectors)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
152 // If this basic block has no vectors then no need to legalize vectors.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153 if (!HasVectors)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 // The legalize process is inherently a bottom-up recursive process (users
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 // legalize their uses before themselves). Given infinite stack space, we
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 // could just start legalizing on the root and traverse the whole graph. In
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 // practice however, this causes us to run out of stack space on large basic
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 // blocks. To avoid this problem, compute an ordering of the nodes where each
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 // node is only legalized after all of its operands are legalized.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 DAG.AssignTopologicalOrder();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
77
|
164 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I)
|
100
|
165 LegalizeOp(SDValue(&*I, 0));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 // Finally, it's possible the root changed. Get the new root.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
168 SDValue OldRoot = DAG.getRoot();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169 assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170 DAG.setRoot(LegalizedNodes[OldRoot]);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
171
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
172 LegalizedNodes.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174 // Remove dead nodes now.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 DAG.RemoveDeadNodes();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 return Changed;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
179
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 SDValue VectorLegalizer::TranslateLegalizeResults(SDValue Op, SDValue Result) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181 // Generic legalization: just pass the operand through.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 for (unsigned i = 0, e = Op.getNode()->getNumValues(); i != e; ++i)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 AddLegalizedOperand(Op.getValue(i), Result.getValue(i));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 return Result.getValue(Op.getResNo());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 // Note that LegalizeOp may be reentered even from single-use nodes, which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 // means that we always must cache transformed nodes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 if (I != LegalizedNodes.end()) return I->second;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 SDNode* Node = Op.getNode();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 // Legalize the operands
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196 SmallVector<SDValue, 8> Ops;
|
95
|
197 for (const SDValue &Op : Node->op_values())
|
|
198 Ops.push_back(LegalizeOp(Op));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199
|
77
|
200 SDValue Result = SDValue(DAG.UpdateNodeOperands(Op.getNode(), Ops), 0);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201
|
95
|
202 bool HasVectorValue = false;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 if (Op.getOpcode() == ISD::LOAD) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 ISD::LoadExtType ExtType = LD->getExtensionType();
|
77
|
206 if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD)
|
83
|
207 switch (TLI.getLoadExtAction(LD->getExtensionType(), LD->getValueType(0),
|
|
208 LD->getMemoryVT())) {
|
77
|
209 default: llvm_unreachable("This action is not supported yet!");
|
|
210 case TargetLowering::Legal:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 return TranslateLegalizeResults(Op, Result);
|
77
|
212 case TargetLowering::Custom:
|
|
213 if (SDValue Lowered = TLI.LowerOperation(Result, DAG)) {
|
95
|
214 if (Lowered == Result)
|
|
215 return TranslateLegalizeResults(Op, Lowered);
|
77
|
216 Changed = true;
|
|
217 if (Lowered->getNumValues() != Op->getNumValues()) {
|
|
218 // This expanded to something other than the load. Assume the
|
|
219 // lowering code took care of any chain values, and just handle the
|
|
220 // returned value.
|
|
221 assert(Result.getValue(1).use_empty() &&
|
|
222 "There are still live users of the old chain!");
|
|
223 return LegalizeOp(Lowered);
|
|
224 }
|
100
|
225 return TranslateLegalizeResults(Op, Lowered);
|
77
|
226 }
|
|
227 case TargetLowering::Expand:
|
|
228 Changed = true;
|
|
229 return LegalizeOp(ExpandLoad(Op));
|
|
230 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 } else if (Op.getOpcode() == ISD::STORE) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233 EVT StVT = ST->getMemoryVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 MVT ValVT = ST->getValue().getSimpleValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 if (StVT.isVector() && ST->isTruncatingStore())
|
100
|
236 switch (TLI.getTruncStoreAction(ValVT, StVT)) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 default: llvm_unreachable("This action is not supported yet!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238 case TargetLowering::Legal:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 return TranslateLegalizeResults(Op, Result);
|
95
|
240 case TargetLowering::Custom: {
|
|
241 SDValue Lowered = TLI.LowerOperation(Result, DAG);
|
|
242 Changed = Lowered != Result;
|
|
243 return TranslateLegalizeResults(Op, Lowered);
|
|
244 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245 case TargetLowering::Expand:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 Changed = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 return LegalizeOp(ExpandStore(Op));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 }
|
100
|
249 } else if (Op.getOpcode() == ISD::MSCATTER || Op.getOpcode() == ISD::MSTORE)
|
95
|
250 HasVectorValue = true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 for (SDNode::value_iterator J = Node->value_begin(), E = Node->value_end();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 J != E;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 ++J)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 HasVectorValue |= J->isVector();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256 if (!HasVectorValue)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
257 return TranslateLegalizeResults(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
258
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
259 EVT QueryType;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
260 switch (Op.getOpcode()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
261 default:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 return TranslateLegalizeResults(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 case ISD::ADD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 case ISD::SUB:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 case ISD::MUL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 case ISD::SDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267 case ISD::UDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 case ISD::SREM:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 case ISD::UREM:
|
100
|
270 case ISD::SDIVREM:
|
|
271 case ISD::UDIVREM:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 case ISD::FADD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 case ISD::FSUB:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 case ISD::FMUL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 case ISD::FDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 case ISD::FREM:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 case ISD::AND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 case ISD::OR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 case ISD::XOR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 case ISD::SHL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 case ISD::SRA:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 case ISD::SRL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 case ISD::ROTL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 case ISD::ROTR:
|
77
|
285 case ISD::BSWAP:
|
100
|
286 case ISD::BITREVERSE:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 case ISD::CTLZ:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 case ISD::CTTZ:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 case ISD::CTLZ_ZERO_UNDEF:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 case ISD::CTTZ_ZERO_UNDEF:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 case ISD::CTPOP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 case ISD::SELECT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 case ISD::VSELECT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
294 case ISD::SELECT_CC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 case ISD::SETCC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 case ISD::ZERO_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 case ISD::ANY_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 case ISD::TRUNCATE:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 case ISD::SIGN_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 case ISD::FP_TO_SINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301 case ISD::FP_TO_UINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 case ISD::FNEG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 case ISD::FABS:
|
83
|
304 case ISD::FMINNUM:
|
|
305 case ISD::FMAXNUM:
|
95
|
306 case ISD::FMINNAN:
|
|
307 case ISD::FMAXNAN:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
308 case ISD::FCOPYSIGN:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309 case ISD::FSQRT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
310 case ISD::FSIN:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
311 case ISD::FCOS:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
312 case ISD::FPOWI:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
313 case ISD::FPOW:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
314 case ISD::FLOG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
315 case ISD::FLOG2:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 case ISD::FLOG10:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 case ISD::FEXP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 case ISD::FEXP2:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
319 case ISD::FCEIL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
320 case ISD::FTRUNC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
321 case ISD::FRINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
322 case ISD::FNEARBYINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
323 case ISD::FROUND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
324 case ISD::FFLOOR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
325 case ISD::FP_ROUND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 case ISD::FP_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327 case ISD::FMA:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 case ISD::SIGN_EXTEND_INREG:
|
77
|
329 case ISD::ANY_EXTEND_VECTOR_INREG:
|
|
330 case ISD::SIGN_EXTEND_VECTOR_INREG:
|
|
331 case ISD::ZERO_EXTEND_VECTOR_INREG:
|
95
|
332 case ISD::SMIN:
|
|
333 case ISD::SMAX:
|
|
334 case ISD::UMIN:
|
|
335 case ISD::UMAX:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
336 QueryType = Node->getValueType(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
337 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
338 case ISD::FP_ROUND_INREG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
339 QueryType = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
341 case ISD::SINT_TO_FP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
342 case ISD::UINT_TO_FP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
343 QueryType = Node->getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
344 break;
|
95
|
345 case ISD::MSCATTER:
|
|
346 QueryType = cast<MaskedScatterSDNode>(Node)->getValue().getValueType();
|
|
347 break;
|
100
|
348 case ISD::MSTORE:
|
|
349 QueryType = cast<MaskedStoreSDNode>(Node)->getValue().getValueType();
|
|
350 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
352
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
353 switch (TLI.getOperationAction(Node->getOpcode(), QueryType)) {
|
100
|
354 default: llvm_unreachable("This action is not supported yet!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
355 case TargetLowering::Promote:
|
77
|
356 Result = Promote(Op);
|
|
357 Changed = true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
358 break;
|
77
|
359 case TargetLowering::Legal:
|
|
360 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
361 case TargetLowering::Custom: {
|
120
|
362 if (SDValue Tmp1 = TLI.LowerOperation(Op, DAG)) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
363 Result = Tmp1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
364 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
365 }
|
120
|
366 LLVM_FALLTHROUGH;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
367 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
368 case TargetLowering::Expand:
|
77
|
369 Result = Expand(Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
370 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
371
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
372 // Make sure that the generated code is itself legal.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
373 if (Result != Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
374 Result = LegalizeOp(Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
375 Changed = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
376 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
377
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
378 // Note that LegalizeOp may be reentered even from single-use nodes, which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
379 // means that we always must cache transformed nodes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
380 AddLegalizedOperand(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 return Result;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383
|
77
|
384 SDValue VectorLegalizer::Promote(SDValue Op) {
|
|
385 // For a few operations there is a specific concept for promotion based on
|
|
386 // the operand's type.
|
|
387 switch (Op.getOpcode()) {
|
|
388 case ISD::SINT_TO_FP:
|
|
389 case ISD::UINT_TO_FP:
|
|
390 // "Promote" the operation by extending the operand.
|
|
391 return PromoteINT_TO_FP(Op);
|
|
392 case ISD::FP_TO_UINT:
|
|
393 case ISD::FP_TO_SINT:
|
|
394 // Promote the operation by extending the operand.
|
|
395 return PromoteFP_TO_INT(Op, Op->getOpcode() == ISD::FP_TO_SINT);
|
|
396 }
|
|
397
|
|
398 // There are currently two cases of vector promotion:
|
|
399 // 1) Bitcasting a vector of integers to a different type to a vector of the
|
95
|
400 // same overall length. For example, x86 promotes ISD::AND v2i32 to v1i64.
|
|
401 // 2) Extending a vector of floats to a vector of the same number of larger
|
77
|
402 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403 MVT VT = Op.getSimpleValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404 assert(Op.getNode()->getNumValues() == 1 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
405 "Can't promote a vector with multiple results!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
406 MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
408 SmallVector<SDValue, 4> Operands(Op.getNumOperands());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
411 if (Op.getOperand(j).getValueType().isVector())
|
77
|
412 if (Op.getOperand(j)
|
|
413 .getValueType()
|
|
414 .getVectorElementType()
|
83
|
415 .isFloatingPoint() &&
|
|
416 NVT.isVector() && NVT.getVectorElementType().isFloatingPoint())
|
77
|
417 Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op.getOperand(j));
|
|
418 else
|
|
419 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
420 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
421 Operands[j] = Op.getOperand(j);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
422 }
|
100
|
423
|
95
|
424 Op = DAG.getNode(Op.getOpcode(), dl, NVT, Operands, Op.getNode()->getFlags());
|
83
|
425 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
|
|
426 (VT.isVector() && VT.getVectorElementType().isFloatingPoint() &&
|
|
427 NVT.isVector() && NVT.getVectorElementType().isFloatingPoint()))
|
95
|
428 return DAG.getNode(ISD::FP_ROUND, dl, VT, Op, DAG.getIntPtrConstant(0, dl));
|
77
|
429 else
|
|
430 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
431 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
432
|
77
|
433 SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
434 // INT_TO_FP operations may require the input operand be promoted even
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
435 // when the type is otherwise legal.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
436 EVT VT = Op.getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
437 assert(Op.getNode()->getNumValues() == 1 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
438 "Can't promote a vector with multiple results!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
439
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
440 // Normal getTypeToPromoteTo() doesn't work here, as that will promote
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
441 // by widening the vector w/ the same element width and twice the number
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
442 // of elements. We want the other way around, the same number of elements,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
443 // each twice the width.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
444 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
445 // Increase the bitwidth of the element to the next pow-of-two
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
446 // (which is greater than 8 bits).
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
447
|
77
|
448 EVT NVT = VT.widenIntegerVectorElementType(*DAG.getContext());
|
|
449 assert(NVT.isSimple() && "Promoting to a non-simple vector type!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
450 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
451 SmallVector<SDValue, 4> Operands(Op.getNumOperands());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
452
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
453 unsigned Opc = Op.getOpcode() == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND :
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
454 ISD::SIGN_EXTEND;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
455 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
456 if (Op.getOperand(j).getValueType().isVector())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
457 Operands[j] = DAG.getNode(Opc, dl, NVT, Op.getOperand(j));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
458 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
459 Operands[j] = Op.getOperand(j);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
460 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
461
|
77
|
462 return DAG.getNode(Op.getOpcode(), dl, Op.getValueType(), Operands);
|
|
463 }
|
|
464
|
|
465 // For FP_TO_INT we promote the result type to a vector type with wider
|
|
466 // elements and then truncate the result. This is different from the default
|
|
467 // PromoteVector which uses bitcast to promote thus assumning that the
|
|
468 // promoted vector type has the same overall size.
|
|
469 SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op, bool isSigned) {
|
|
470 assert(Op.getNode()->getNumValues() == 1 &&
|
|
471 "Can't promote a vector with multiple results!");
|
|
472 EVT VT = Op.getValueType();
|
|
473
|
|
474 EVT NewVT;
|
|
475 unsigned NewOpc;
|
|
476 while (1) {
|
|
477 NewVT = VT.widenIntegerVectorElementType(*DAG.getContext());
|
|
478 assert(NewVT.isSimple() && "Promoting to a non-simple vector type!");
|
|
479 if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) {
|
|
480 NewOpc = ISD::FP_TO_SINT;
|
|
481 break;
|
|
482 }
|
|
483 if (!isSigned && TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewVT)) {
|
|
484 NewOpc = ISD::FP_TO_UINT;
|
|
485 break;
|
|
486 }
|
|
487 }
|
|
488
|
|
489 SDLoc loc(Op);
|
|
490 SDValue promoted = DAG.getNode(NewOpc, SDLoc(Op), NewVT, Op.getOperand(0));
|
|
491 return DAG.getNode(ISD::TRUNCATE, SDLoc(Op), VT, promoted);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
492 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
493
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
494
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
495 SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
496 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
|
120
|
497
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
498 EVT SrcVT = LD->getMemoryVT();
|
120
|
499 EVT SrcEltVT = SrcVT.getScalarType();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
500 unsigned NumElem = SrcVT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
501
|
120
|
502
|
|
503 SDValue NewChain;
|
|
504 SDValue Value;
|
|
505 if (SrcVT.getVectorNumElements() > 1 && !SrcEltVT.isByteSized()) {
|
|
506 SDLoc dl(Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
507
|
120
|
508 SmallVector<SDValue, 8> Vals;
|
|
509 SmallVector<SDValue, 8> LoadChains;
|
|
510
|
|
511 EVT DstEltVT = LD->getValueType(0).getScalarType();
|
|
512 SDValue Chain = LD->getChain();
|
|
513 SDValue BasePTR = LD->getBasePtr();
|
|
514 ISD::LoadExtType ExtType = LD->getExtensionType();
|
|
515
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
516 // When elements in a vector is not byte-addressable, we cannot directly
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
517 // load each element by advancing pointer, which could only address bytes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
518 // Instead, we load all significant words, mask bits off, and concatenate
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
519 // them to form each element. Finally, they are extended to destination
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
520 // scalar type to build the destination vector.
|
95
|
521 EVT WideVT = TLI.getPointerTy(DAG.getDataLayout());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
522
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
523 assert(WideVT.isRound() &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
524 "Could not handle the sophisticated case when the widest integer is"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
525 " not power of 2.");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
526 assert(WideVT.bitsGE(SrcEltVT) &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
527 "Type is not legalized?");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
528
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
529 unsigned WideBytes = WideVT.getStoreSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
530 unsigned Offset = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
531 unsigned RemainingBytes = SrcVT.getStoreSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
532 SmallVector<SDValue, 8> LoadVals;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
533
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
534 while (RemainingBytes > 0) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
535 SDValue ScalarLoad;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
536 unsigned LoadBytes = WideBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
537
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
538 if (RemainingBytes >= LoadBytes) {
|
120
|
539 ScalarLoad =
|
|
540 DAG.getLoad(WideVT, dl, Chain, BasePTR,
|
|
541 LD->getPointerInfo().getWithOffset(Offset),
|
|
542 MinAlign(LD->getAlignment(), Offset),
|
|
543 LD->getMemOperand()->getFlags(), LD->getAAInfo());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
544 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
545 EVT LoadVT = WideVT;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
546 while (RemainingBytes < LoadBytes) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
547 LoadBytes >>= 1; // Reduce the load size by half.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
548 LoadVT = EVT::getIntegerVT(*DAG.getContext(), LoadBytes << 3);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
549 }
|
120
|
550 ScalarLoad =
|
|
551 DAG.getExtLoad(ISD::EXTLOAD, dl, WideVT, Chain, BasePTR,
|
|
552 LD->getPointerInfo().getWithOffset(Offset), LoadVT,
|
|
553 MinAlign(LD->getAlignment(), Offset),
|
|
554 LD->getMemOperand()->getFlags(), LD->getAAInfo());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
555 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
556
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
557 RemainingBytes -= LoadBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
558 Offset += LoadBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
559 BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
|
95
|
560 DAG.getConstant(LoadBytes, dl,
|
|
561 BasePTR.getValueType()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
562
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
563 LoadVals.push_back(ScalarLoad.getValue(0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
564 LoadChains.push_back(ScalarLoad.getValue(1));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
565 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
566
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
567 // Extract bits, pack and extend/trunc them into destination type.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
568 unsigned SrcEltBits = SrcEltVT.getSizeInBits();
|
95
|
569 SDValue SrcEltBitMask = DAG.getConstant((1U << SrcEltBits) - 1, dl, WideVT);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
570
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
571 unsigned BitOffset = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
572 unsigned WideIdx = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
573 unsigned WideBits = WideVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
574
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
575 for (unsigned Idx = 0; Idx != NumElem; ++Idx) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
576 SDValue Lo, Hi, ShAmt;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
577
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
578 if (BitOffset < WideBits) {
|
95
|
579 ShAmt = DAG.getConstant(
|
|
580 BitOffset, dl, TLI.getShiftAmountTy(WideVT, DAG.getDataLayout()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
581 Lo = DAG.getNode(ISD::SRL, dl, WideVT, LoadVals[WideIdx], ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
582 Lo = DAG.getNode(ISD::AND, dl, WideVT, Lo, SrcEltBitMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
583 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
584
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
585 BitOffset += SrcEltBits;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
586 if (BitOffset >= WideBits) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
587 WideIdx++;
|
83
|
588 BitOffset -= WideBits;
|
|
589 if (BitOffset > 0) {
|
95
|
590 ShAmt = DAG.getConstant(
|
|
591 SrcEltBits - BitOffset, dl,
|
|
592 TLI.getShiftAmountTy(WideVT, DAG.getDataLayout()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
593 Hi = DAG.getNode(ISD::SHL, dl, WideVT, LoadVals[WideIdx], ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
594 Hi = DAG.getNode(ISD::AND, dl, WideVT, Hi, SrcEltBitMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
595 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
596 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
597
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
598 if (Hi.getNode())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
599 Lo = DAG.getNode(ISD::OR, dl, WideVT, Lo, Hi);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
600
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
601 switch (ExtType) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
602 default: llvm_unreachable("Unknown extended-load op!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
603 case ISD::EXTLOAD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
604 Lo = DAG.getAnyExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
605 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
606 case ISD::ZEXTLOAD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
607 Lo = DAG.getZExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
608 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
609 case ISD::SEXTLOAD:
|
95
|
610 ShAmt =
|
|
611 DAG.getConstant(WideBits - SrcEltBits, dl,
|
|
612 TLI.getShiftAmountTy(WideVT, DAG.getDataLayout()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
613 Lo = DAG.getNode(ISD::SHL, dl, WideVT, Lo, ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
614 Lo = DAG.getNode(ISD::SRA, dl, WideVT, Lo, ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
615 Lo = DAG.getSExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
616 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
617 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
618 Vals.push_back(Lo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
619 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
620
|
120
|
621 NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
|
|
622 Value = DAG.getNode(ISD::BUILD_VECTOR, dl,
|
|
623 Op.getNode()->getValueType(0), Vals);
|
|
624 } else {
|
|
625 SDValue Scalarized = TLI.scalarizeVectorLoad(LD, DAG);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
626
|
120
|
627 NewChain = Scalarized.getValue(1);
|
|
628 Value = Scalarized.getValue(0);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
629 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
630
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
631 AddLegalizedOperand(Op.getValue(0), Value);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
632 AddLegalizedOperand(Op.getValue(1), NewChain);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
633
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
634 return (Op.getResNo() ? NewChain : Value);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
635 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
636
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
637 SDValue VectorLegalizer::ExpandStore(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
638 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
639
|
120
|
640 EVT StVT = ST->getMemoryVT();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
641 EVT MemSclVT = StVT.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
642 unsigned ScalarSize = MemSclVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
643
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
644 // Round odd types to the next pow of two.
|
120
|
645 if (!isPowerOf2_32(ScalarSize)) {
|
|
646 // FIXME: This is completely broken and inconsistent with ExpandLoad
|
|
647 // handling.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
648
|
120
|
649 // For sub-byte element sizes, this ends up with 0 stride between elements,
|
|
650 // so the same element just gets re-written to the same location. There seem
|
|
651 // to be tests explicitly testing for this broken behavior though. tests
|
|
652 // for this broken behavior.
|
|
653
|
|
654 LLVMContext &Ctx = *DAG.getContext();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
655
|
120
|
656 EVT NewMemVT
|
|
657 = EVT::getVectorVT(Ctx,
|
|
658 MemSclVT.getIntegerVT(Ctx, NextPowerOf2(ScalarSize)),
|
|
659 StVT.getVectorNumElements());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
660
|
120
|
661 SDValue NewVectorStore = DAG.getTruncStore(
|
|
662 ST->getChain(), SDLoc(Op), ST->getValue(), ST->getBasePtr(),
|
|
663 ST->getPointerInfo(), NewMemVT, ST->getAlignment(),
|
|
664 ST->getMemOperand()->getFlags(), ST->getAAInfo());
|
|
665 ST = cast<StoreSDNode>(NewVectorStore.getNode());
|
|
666 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
667
|
120
|
668 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
669 AddLegalizedOperand(Op, TF);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
670 return TF;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
671 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
672
|
77
|
673 SDValue VectorLegalizer::Expand(SDValue Op) {
|
|
674 switch (Op->getOpcode()) {
|
|
675 case ISD::SIGN_EXTEND_INREG:
|
|
676 return ExpandSEXTINREG(Op);
|
|
677 case ISD::ANY_EXTEND_VECTOR_INREG:
|
|
678 return ExpandANY_EXTEND_VECTOR_INREG(Op);
|
|
679 case ISD::SIGN_EXTEND_VECTOR_INREG:
|
|
680 return ExpandSIGN_EXTEND_VECTOR_INREG(Op);
|
|
681 case ISD::ZERO_EXTEND_VECTOR_INREG:
|
|
682 return ExpandZERO_EXTEND_VECTOR_INREG(Op);
|
|
683 case ISD::BSWAP:
|
|
684 return ExpandBSWAP(Op);
|
|
685 case ISD::VSELECT:
|
|
686 return ExpandVSELECT(Op);
|
|
687 case ISD::SELECT:
|
|
688 return ExpandSELECT(Op);
|
|
689 case ISD::UINT_TO_FP:
|
|
690 return ExpandUINT_TO_FLOAT(Op);
|
|
691 case ISD::FNEG:
|
|
692 return ExpandFNEG(Op);
|
|
693 case ISD::SETCC:
|
|
694 return UnrollVSETCC(Op);
|
100
|
695 case ISD::BITREVERSE:
|
|
696 return ExpandBITREVERSE(Op);
|
120
|
697 case ISD::CTLZ:
|
100
|
698 case ISD::CTLZ_ZERO_UNDEF:
|
120
|
699 return ExpandCTLZ(Op);
|
100
|
700 case ISD::CTTZ_ZERO_UNDEF:
|
120
|
701 return ExpandCTTZ_ZERO_UNDEF(Op);
|
77
|
702 default:
|
|
703 return DAG.UnrollVectorOp(Op.getNode());
|
|
704 }
|
|
705 }
|
|
706
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
707 SDValue VectorLegalizer::ExpandSELECT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
708 // Lower a select instruction where the condition is a scalar and the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
709 // operands are vectors. Lower this select to VSELECT and implement it
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
710 // using XOR AND OR. The selector bit is broadcasted.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
711 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
712 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
713
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
714 SDValue Mask = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
715 SDValue Op1 = Op.getOperand(1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
716 SDValue Op2 = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
717
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
718 assert(VT.isVector() && !Mask.getValueType().isVector()
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
719 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
720
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
721 unsigned NumElem = VT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
722
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
723 // If we can't even use the basic vector operations of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
724 // AND,OR,XOR, we will have to scalarize the op.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
725 // Notice that the operation may be 'promoted' which means that it is
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
726 // 'bitcasted' to another type which is handled.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
727 // Also, we need to be able to construct a splat vector using BUILD_VECTOR.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
728 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
729 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
730 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
731 TLI.getOperationAction(ISD::BUILD_VECTOR, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
732 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
733
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
734 // Generate a mask operand.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
735 EVT MaskTy = VT.changeVectorElementTypeToInteger();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
736
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
737 // What is the size of each element in the vector mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
738 EVT BitTy = MaskTy.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
739
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
740 Mask = DAG.getSelect(DL, BitTy, Mask,
|
95
|
741 DAG.getConstant(APInt::getAllOnesValue(BitTy.getSizeInBits()), DL,
|
|
742 BitTy),
|
|
743 DAG.getConstant(0, DL, BitTy));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
744
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
745 // Broadcast the mask so that the entire vector is all-one or all zero.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
746 SmallVector<SDValue, 8> Ops(NumElem, Mask);
|
77
|
747 Mask = DAG.getNode(ISD::BUILD_VECTOR, DL, MaskTy, Ops);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
748
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
749 // Bitcast the operands to be the same type as the mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
750 // This is needed when we select between FP types because
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
751 // the mask is a vector of integers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
752 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
753 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
754
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
755 SDValue AllOnes = DAG.getConstant(
|
95
|
756 APInt::getAllOnesValue(BitTy.getSizeInBits()), DL, MaskTy);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
757 SDValue NotMask = DAG.getNode(ISD::XOR, DL, MaskTy, Mask, AllOnes);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
758
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
759 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
760 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
761 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
762 return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
763 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
764
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
765 SDValue VectorLegalizer::ExpandSEXTINREG(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
766 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
767
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
768 // Make sure that the SRA and SHL instructions are available.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
769 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
770 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
771 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
772
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
773 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
774 EVT OrigTy = cast<VTSDNode>(Op->getOperand(1))->getVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
775
|
120
|
776 unsigned BW = VT.getScalarSizeInBits();
|
|
777 unsigned OrigBW = OrigTy.getScalarSizeInBits();
|
95
|
778 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, DL, VT);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
779
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
780 Op = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
781 Op = DAG.getNode(ISD::SHL, DL, VT, Op, ShiftSz);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
782 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
783 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
784
|
77
|
785 // Generically expand a vector anyext in register to a shuffle of the relevant
|
|
786 // lanes into the appropriate locations, with other lanes left undef.
|
|
787 SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
788 SDLoc DL(Op);
|
|
789 EVT VT = Op.getValueType();
|
|
790 int NumElements = VT.getVectorNumElements();
|
|
791 SDValue Src = Op.getOperand(0);
|
|
792 EVT SrcVT = Src.getValueType();
|
|
793 int NumSrcElements = SrcVT.getVectorNumElements();
|
|
794
|
|
795 // Build a base mask of undef shuffles.
|
|
796 SmallVector<int, 16> ShuffleMask;
|
|
797 ShuffleMask.resize(NumSrcElements, -1);
|
|
798
|
|
799 // Place the extended lanes into the correct locations.
|
|
800 int ExtLaneScale = NumSrcElements / NumElements;
|
95
|
801 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
|
77
|
802 for (int i = 0; i < NumElements; ++i)
|
|
803 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
|
|
804
|
|
805 return DAG.getNode(
|
|
806 ISD::BITCAST, DL, VT,
|
|
807 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getUNDEF(SrcVT), ShuffleMask));
|
|
808 }
|
|
809
|
|
810 SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
811 SDLoc DL(Op);
|
|
812 EVT VT = Op.getValueType();
|
|
813 SDValue Src = Op.getOperand(0);
|
|
814 EVT SrcVT = Src.getValueType();
|
|
815
|
|
816 // First build an any-extend node which can be legalized above when we
|
|
817 // recurse through it.
|
|
818 Op = DAG.getAnyExtendVectorInReg(Src, DL, VT);
|
|
819
|
|
820 // Now we need sign extend. Do this by shifting the elements. Even if these
|
|
821 // aren't legal operations, they have a better chance of being legalized
|
|
822 // without full scalarization than the sign extension does.
|
120
|
823 unsigned EltWidth = VT.getScalarSizeInBits();
|
|
824 unsigned SrcEltWidth = SrcVT.getScalarSizeInBits();
|
95
|
825 SDValue ShiftAmount = DAG.getConstant(EltWidth - SrcEltWidth, DL, VT);
|
77
|
826 return DAG.getNode(ISD::SRA, DL, VT,
|
|
827 DAG.getNode(ISD::SHL, DL, VT, Op, ShiftAmount),
|
|
828 ShiftAmount);
|
|
829 }
|
|
830
|
|
831 // Generically expand a vector zext in register to a shuffle of the relevant
|
|
832 // lanes into the appropriate locations, a blend of zero into the high bits,
|
|
833 // and a bitcast to the wider element type.
|
|
834 SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
835 SDLoc DL(Op);
|
|
836 EVT VT = Op.getValueType();
|
|
837 int NumElements = VT.getVectorNumElements();
|
|
838 SDValue Src = Op.getOperand(0);
|
|
839 EVT SrcVT = Src.getValueType();
|
|
840 int NumSrcElements = SrcVT.getVectorNumElements();
|
|
841
|
|
842 // Build up a zero vector to blend into this one.
|
120
|
843 SDValue Zero = DAG.getConstant(0, DL, SrcVT);
|
77
|
844
|
|
845 // Shuffle the incoming lanes into the correct position, and pull all other
|
|
846 // lanes from the zero vector.
|
|
847 SmallVector<int, 16> ShuffleMask;
|
|
848 ShuffleMask.reserve(NumSrcElements);
|
|
849 for (int i = 0; i < NumSrcElements; ++i)
|
|
850 ShuffleMask.push_back(i);
|
|
851
|
|
852 int ExtLaneScale = NumSrcElements / NumElements;
|
95
|
853 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
|
77
|
854 for (int i = 0; i < NumElements; ++i)
|
|
855 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
|
|
856
|
|
857 return DAG.getNode(ISD::BITCAST, DL, VT,
|
|
858 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
|
|
859 }
|
|
860
|
120
|
861 static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
|
|
862 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
|
|
863 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
|
|
864 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
|
|
865 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
|
|
866 }
|
|
867
|
77
|
868 SDValue VectorLegalizer::ExpandBSWAP(SDValue Op) {
|
|
869 EVT VT = Op.getValueType();
|
|
870
|
|
871 // Generate a byte wise shuffle mask for the BSWAP.
|
|
872 SmallVector<int, 16> ShuffleMask;
|
120
|
873 createBSWAPShuffleMask(VT, ShuffleMask);
|
77
|
874 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
|
|
875
|
|
876 // Only emit a shuffle if the mask is legal.
|
|
877 if (!TLI.isShuffleMaskLegal(ShuffleMask, ByteVT))
|
|
878 return DAG.UnrollVectorOp(Op.getNode());
|
|
879
|
|
880 SDLoc DL(Op);
|
|
881 Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Op.getOperand(0));
|
120
|
882 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT), ShuffleMask);
|
77
|
883 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
|
|
884 }
|
|
885
|
100
|
886 SDValue VectorLegalizer::ExpandBITREVERSE(SDValue Op) {
|
|
887 EVT VT = Op.getValueType();
|
|
888
|
|
889 // If we have the scalar operation, it's probably cheaper to unroll it.
|
|
890 if (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, VT.getScalarType()))
|
|
891 return DAG.UnrollVectorOp(Op.getNode());
|
|
892
|
120
|
893 // If the vector element width is a whole number of bytes, test if its legal
|
|
894 // to BSWAP shuffle the bytes and then perform the BITREVERSE on the byte
|
|
895 // vector. This greatly reduces the number of bit shifts necessary.
|
|
896 unsigned ScalarSizeInBits = VT.getScalarSizeInBits();
|
|
897 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
|
|
898 SmallVector<int, 16> BSWAPMask;
|
|
899 createBSWAPShuffleMask(VT, BSWAPMask);
|
|
900
|
|
901 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, BSWAPMask.size());
|
|
902 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
|
|
903 (TLI.isOperationLegalOrCustom(ISD::BITREVERSE, ByteVT) ||
|
|
904 (TLI.isOperationLegalOrCustom(ISD::SHL, ByteVT) &&
|
|
905 TLI.isOperationLegalOrCustom(ISD::SRL, ByteVT) &&
|
|
906 TLI.isOperationLegalOrCustomOrPromote(ISD::AND, ByteVT) &&
|
|
907 TLI.isOperationLegalOrCustomOrPromote(ISD::OR, ByteVT)))) {
|
|
908 SDLoc DL(Op);
|
|
909 Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Op.getOperand(0));
|
|
910 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT),
|
|
911 BSWAPMask);
|
|
912 Op = DAG.getNode(ISD::BITREVERSE, DL, ByteVT, Op);
|
|
913 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
|
|
914 }
|
|
915 }
|
|
916
|
100
|
917 // If we have the appropriate vector bit operations, it is better to use them
|
|
918 // than unrolling and expanding each component.
|
|
919 if (!TLI.isOperationLegalOrCustom(ISD::SHL, VT) ||
|
|
920 !TLI.isOperationLegalOrCustom(ISD::SRL, VT) ||
|
120
|
921 !TLI.isOperationLegalOrCustomOrPromote(ISD::AND, VT) ||
|
|
922 !TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT))
|
100
|
923 return DAG.UnrollVectorOp(Op.getNode());
|
|
924
|
|
925 // Let LegalizeDAG handle this later.
|
|
926 return Op;
|
|
927 }
|
|
928
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
929 SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
930 // Implement VSELECT in terms of XOR, AND, OR
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
931 // on platforms which do not support blend natively.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
932 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
933
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
934 SDValue Mask = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
935 SDValue Op1 = Op.getOperand(1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
936 SDValue Op2 = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
937
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
938 EVT VT = Mask.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
939
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
940 // If we can't even use the basic vector operations of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
941 // AND,OR,XOR, we will have to scalarize the op.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
942 // Notice that the operation may be 'promoted' which means that it is
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
943 // 'bitcasted' to another type which is handled.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
944 // This operation also isn't safe with AND, OR, XOR when the boolean
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
945 // type is 0/1 as we need an all ones vector constant to mask with.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
946 // FIXME: Sign extend 1 to all ones if thats legal on the target.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
947 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
948 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
|
77
|
949 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
|
|
950 TLI.getBooleanContents(Op1.getValueType()) !=
|
|
951 TargetLowering::ZeroOrNegativeOneBooleanContent)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
952 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
953
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
954 // If the mask and the type are different sizes, unroll the vector op. This
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
955 // can occur when getSetCCResultType returns something that is different in
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
956 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
|
120
|
957 if (VT.getSizeInBits() != Op1.getValueSizeInBits())
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
958 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
959
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
960 // Bitcast the operands to be the same type as the mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
961 // This is needed when we select between FP types because
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
962 // the mask is a vector of integers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
963 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
964 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
965
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
966 SDValue AllOnes = DAG.getConstant(
|
120
|
967 APInt::getAllOnesValue(VT.getScalarSizeInBits()), DL, VT);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
968 SDValue NotMask = DAG.getNode(ISD::XOR, DL, VT, Mask, AllOnes);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
969
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
970 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
971 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
972 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
973 return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
974 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
975
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
976 SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
977 EVT VT = Op.getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
978 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
979
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
980 // Make sure that the SINT_TO_FP and SRL instructions are available.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
981 if (TLI.getOperationAction(ISD::SINT_TO_FP, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
982 TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
983 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
984
|
120
|
985 unsigned BW = VT.getScalarSizeInBits();
|
|
986 assert((BW == 64 || BW == 32) &&
|
|
987 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
988
|
120
|
989 SDValue HalfWord = DAG.getConstant(BW / 2, DL, VT);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
990
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
991 // Constants to clear the upper part of the word.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
992 // Notice that we can also use SHL+SHR, but using a constant is slightly
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
993 // faster on x86.
|
120
|
994 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
|
95
|
995 SDValue HalfWordMask = DAG.getConstant(HWMask, DL, VT);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
996
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
997 // Two to the power of half-word-size.
|
120
|
998 SDValue TWOHW = DAG.getConstantFP(1 << (BW / 2), DL, Op.getValueType());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
999
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1000 // Clear upper part of LO, lower HI
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1001 SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Op.getOperand(0), HalfWord);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1002 SDValue LO = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), HalfWordMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1003
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1004 // Convert hi and lo to floats
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1005 // Convert the hi part back to the upper values
|
95
|
1006 // TODO: Can any fast-math-flags be set on these nodes?
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1007 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), HI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1008 fHI = DAG.getNode(ISD::FMUL, DL, Op.getValueType(), fHI, TWOHW);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1009 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), LO);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1010
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1011 // Add the two halves
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1012 return DAG.getNode(ISD::FADD, DL, Op.getValueType(), fHI, fLO);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1013 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1014
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1015 SDValue VectorLegalizer::ExpandFNEG(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1016 if (TLI.isOperationLegalOrCustom(ISD::FSUB, Op.getValueType())) {
|
95
|
1017 SDLoc DL(Op);
|
|
1018 SDValue Zero = DAG.getConstantFP(-0.0, DL, Op.getValueType());
|
|
1019 // TODO: If FNEG had fast-math-flags, they'd get propagated to this FSUB.
|
|
1020 return DAG.getNode(ISD::FSUB, DL, Op.getValueType(),
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1021 Zero, Op.getOperand(0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1022 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1023 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1024 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1025
|
120
|
1026 SDValue VectorLegalizer::ExpandCTLZ(SDValue Op) {
|
|
1027 EVT VT = Op.getValueType();
|
|
1028 unsigned NumBitsPerElt = VT.getScalarSizeInBits();
|
|
1029
|
|
1030 // If the non-ZERO_UNDEF version is supported we can use that instead.
|
|
1031 if (Op.getOpcode() == ISD::CTLZ_ZERO_UNDEF &&
|
|
1032 TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) {
|
|
1033 SDLoc DL(Op);
|
|
1034 return DAG.getNode(ISD::CTLZ, DL, Op.getValueType(), Op.getOperand(0));
|
|
1035 }
|
|
1036
|
|
1037 // If CTPOP is available we can lower with a CTPOP based method:
|
|
1038 // u16 ctlz(u16 x) {
|
|
1039 // x |= (x >> 1);
|
|
1040 // x |= (x >> 2);
|
|
1041 // x |= (x >> 4);
|
|
1042 // x |= (x >> 8);
|
|
1043 // return ctpop(~x);
|
|
1044 // }
|
|
1045 // Ref: "Hacker's Delight" by Henry Warren
|
|
1046 if (isPowerOf2_32(NumBitsPerElt) &&
|
|
1047 TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) &&
|
|
1048 TLI.isOperationLegalOrCustom(ISD::SRL, VT) &&
|
|
1049 TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT) &&
|
|
1050 TLI.isOperationLegalOrCustomOrPromote(ISD::XOR, VT)) {
|
|
1051 SDLoc DL(Op);
|
|
1052 SDValue Res = Op.getOperand(0);
|
|
1053 EVT ShiftTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
|
|
1054
|
|
1055 for (unsigned i = 1; i != NumBitsPerElt; i *= 2)
|
|
1056 Res = DAG.getNode(
|
|
1057 ISD::OR, DL, VT, Res,
|
|
1058 DAG.getNode(ISD::SRL, DL, VT, Res, DAG.getConstant(i, DL, ShiftTy)));
|
|
1059
|
|
1060 Res = DAG.getNOT(DL, Res, VT);
|
|
1061 return DAG.getNode(ISD::CTPOP, DL, VT, Res);
|
|
1062 }
|
|
1063
|
|
1064 // Otherwise go ahead and unroll.
|
|
1065 return DAG.UnrollVectorOp(Op.getNode());
|
|
1066 }
|
|
1067
|
|
1068 SDValue VectorLegalizer::ExpandCTTZ_ZERO_UNDEF(SDValue Op) {
|
|
1069 // If the non-ZERO_UNDEF version is supported we can use that instead.
|
|
1070 if (TLI.isOperationLegalOrCustom(ISD::CTTZ, Op.getValueType())) {
|
|
1071 SDLoc DL(Op);
|
|
1072 return DAG.getNode(ISD::CTTZ, DL, Op.getValueType(), Op.getOperand(0));
|
|
1073 }
|
100
|
1074
|
|
1075 // Otherwise go ahead and unroll.
|
|
1076 return DAG.UnrollVectorOp(Op.getNode());
|
|
1077 }
|
|
1078
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1079 SDValue VectorLegalizer::UnrollVSETCC(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1080 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1081 unsigned NumElems = VT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1082 EVT EltVT = VT.getVectorElementType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1083 SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1), CC = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1084 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1085 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1086 SmallVector<SDValue, 8> Ops(NumElems);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1087 for (unsigned i = 0; i < NumElems; ++i) {
|
95
|
1088 SDValue LHSElem = DAG.getNode(
|
|
1089 ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
|
|
1090 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
|
|
1091 SDValue RHSElem = DAG.getNode(
|
|
1092 ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
|
|
1093 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1094 Ops[i] = DAG.getNode(ISD::SETCC, dl,
|
95
|
1095 TLI.getSetCCResultType(DAG.getDataLayout(),
|
|
1096 *DAG.getContext(), TmpEltVT),
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1097 LHSElem, RHSElem, CC);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1098 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1099 DAG.getConstant(APInt::getAllOnesValue
|
95
|
1100 (EltVT.getSizeInBits()), dl, EltVT),
|
|
1101 DAG.getConstant(0, dl, EltVT));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1102 }
|
77
|
1103 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1104 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1105
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1106 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1107
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1108 bool SelectionDAG::LegalizeVectors() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1109 return VectorLegalizer(*this).Run();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1110 }
|