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);
|
77
|
108
|
|
109 /// \brief Implements vector promotion.
|
|
110 ///
|
|
111 /// This is essentially just bitcasting the operands to a different type and
|
|
112 /// bitcasting the result back to the original type.
|
|
113 SDValue Promote(SDValue Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114
|
77
|
115 /// \brief Implements [SU]INT_TO_FP vector promotion.
|
|
116 ///
|
|
117 /// This is a [zs]ext of the input operand to the next size up.
|
|
118 SDValue PromoteINT_TO_FP(SDValue Op);
|
|
119
|
|
120 /// \brief Implements FP_TO_[SU]INT vector promotion of the result type.
|
|
121 ///
|
|
122 /// It is promoted to the next size up integer type. The result is then
|
|
123 /// truncated back to the original type.
|
|
124 SDValue PromoteFP_TO_INT(SDValue Op, bool isSigned);
|
|
125
|
|
126 public:
|
|
127 /// \brief Begin legalizer the vector operations in the DAG.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 bool Run();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129 VectorLegalizer(SelectionDAG& dag) :
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 DAG(dag), TLI(dag.getTargetLoweringInfo()), Changed(false) {}
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
133 bool VectorLegalizer::Run() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
134 // Before we start legalizing vector nodes, check if there are any vectors.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 bool HasVectors = false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
77
|
137 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 // 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
|
139 // the operands because we are going to check their values at some point.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
140 for (SDNode::value_iterator J = I->value_begin(), E = I->value_end();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 J != E; ++J)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 HasVectors |= J->isVector();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144 // If we found a vector node we can start the legalization.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 if (HasVectors)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 // If this basic block has no vectors then no need to legalize vectors.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 if (!HasVectors)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
152
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153 // The legalize process is inherently a bottom-up recursive process (users
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 // legalize their uses before themselves). Given infinite stack space, we
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155 // could just start legalizing on the root and traverse the whole graph. In
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 // 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
|
157 // blocks. To avoid this problem, compute an ordering of the nodes where each
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 // node is only legalized after all of its operands are legalized.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 DAG.AssignTopologicalOrder();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
77
|
161 E = std::prev(DAG.allnodes_end()); I != std::next(E); ++I)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 LegalizeOp(SDValue(I, 0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
164 // Finally, it's possible the root changed. Get the new root.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 SDValue OldRoot = DAG.getRoot();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166 assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 DAG.setRoot(LegalizedNodes[OldRoot]);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
168
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169 LegalizedNodes.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
171 // Remove dead nodes now.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
172 DAG.RemoveDeadNodes();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174 return Changed;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 SDValue VectorLegalizer::TranslateLegalizeResults(SDValue Op, SDValue Result) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178 // Generic legalization: just pass the operand through.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
179 for (unsigned i = 0, e = Op.getNode()->getNumValues(); i != e; ++i)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 AddLegalizedOperand(Op.getValue(i), Result.getValue(i));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181 return Result.getValue(Op.getResNo());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 // Note that LegalizeOp may be reentered even from single-use nodes, which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186 // means that we always must cache transformed nodes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 if (I != LegalizedNodes.end()) return I->second;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 SDNode* Node = Op.getNode();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 // Legalize the operands
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 SmallVector<SDValue, 8> Ops;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 Ops.push_back(LegalizeOp(Node->getOperand(i)));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196
|
77
|
197 SDValue Result = SDValue(DAG.UpdateNodeOperands(Op.getNode(), Ops), 0);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 if (Op.getOpcode() == ISD::LOAD) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201 ISD::LoadExtType ExtType = LD->getExtensionType();
|
77
|
202 if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD)
|
83
|
203 switch (TLI.getLoadExtAction(LD->getExtensionType(), LD->getValueType(0),
|
|
204 LD->getMemoryVT())) {
|
77
|
205 default: llvm_unreachable("This action is not supported yet!");
|
|
206 case TargetLowering::Legal:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 return TranslateLegalizeResults(Op, Result);
|
77
|
208 case TargetLowering::Custom:
|
|
209 if (SDValue Lowered = TLI.LowerOperation(Result, DAG)) {
|
|
210 Changed = true;
|
|
211 if (Lowered->getNumValues() != Op->getNumValues()) {
|
|
212 // This expanded to something other than the load. Assume the
|
|
213 // lowering code took care of any chain values, and just handle the
|
|
214 // returned value.
|
|
215 assert(Result.getValue(1).use_empty() &&
|
|
216 "There are still live users of the old chain!");
|
|
217 return LegalizeOp(Lowered);
|
|
218 } else {
|
|
219 return TranslateLegalizeResults(Op, Lowered);
|
|
220 }
|
|
221 }
|
|
222 case TargetLowering::Expand:
|
|
223 Changed = true;
|
|
224 return LegalizeOp(ExpandLoad(Op));
|
|
225 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 } else if (Op.getOpcode() == ISD::STORE) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 EVT StVT = ST->getMemoryVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 MVT ValVT = ST->getValue().getSimpleValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 if (StVT.isVector() && ST->isTruncatingStore())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 switch (TLI.getTruncStoreAction(ValVT, StVT.getSimpleVT())) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 default: llvm_unreachable("This action is not supported yet!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233 case TargetLowering::Legal:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 return TranslateLegalizeResults(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 case TargetLowering::Custom:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236 Changed = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 return TranslateLegalizeResults(Op, TLI.LowerOperation(Result, DAG));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238 case TargetLowering::Expand:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 Changed = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 return LegalizeOp(ExpandStore(Op));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
241 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 bool HasVectorValue = false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245 for (SDNode::value_iterator J = Node->value_begin(), E = Node->value_end();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 J != E;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 ++J)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 HasVectorValue |= J->isVector();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249 if (!HasVectorValue)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250 return TranslateLegalizeResults(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 EVT QueryType;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 switch (Op.getOpcode()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 default:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 return TranslateLegalizeResults(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256 case ISD::ADD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
257 case ISD::SUB:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
258 case ISD::MUL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
259 case ISD::SDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
260 case ISD::UDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
261 case ISD::SREM:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 case ISD::UREM:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 case ISD::FADD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 case ISD::FSUB:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 case ISD::FMUL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 case ISD::FDIV:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267 case ISD::FREM:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 case ISD::AND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 case ISD::OR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270 case ISD::XOR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 case ISD::SHL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 case ISD::SRA:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 case ISD::SRL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 case ISD::ROTL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 case ISD::ROTR:
|
77
|
276 case ISD::BSWAP:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 case ISD::CTLZ:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 case ISD::CTTZ:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 case ISD::CTLZ_ZERO_UNDEF:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 case ISD::CTTZ_ZERO_UNDEF:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 case ISD::CTPOP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 case ISD::SELECT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 case ISD::VSELECT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 case ISD::SELECT_CC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 case ISD::SETCC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
286 case ISD::ZERO_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 case ISD::ANY_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 case ISD::TRUNCATE:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 case ISD::SIGN_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 case ISD::FP_TO_SINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 case ISD::FP_TO_UINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 case ISD::FNEG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 case ISD::FABS:
|
83
|
294 case ISD::FMINNUM:
|
|
295 case ISD::FMAXNUM:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 case ISD::FCOPYSIGN:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 case ISD::FSQRT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 case ISD::FSIN:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 case ISD::FCOS:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 case ISD::FPOWI:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301 case ISD::FPOW:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 case ISD::FLOG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 case ISD::FLOG2:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
304 case ISD::FLOG10:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
305 case ISD::FEXP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
306 case ISD::FEXP2:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
307 case ISD::FCEIL:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
308 case ISD::FTRUNC:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309 case ISD::FRINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
310 case ISD::FNEARBYINT:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
311 case ISD::FROUND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
312 case ISD::FFLOOR:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
313 case ISD::FP_ROUND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
314 case ISD::FP_EXTEND:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
315 case ISD::FMA:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 case ISD::SIGN_EXTEND_INREG:
|
77
|
317 case ISD::ANY_EXTEND_VECTOR_INREG:
|
|
318 case ISD::SIGN_EXTEND_VECTOR_INREG:
|
|
319 case ISD::ZERO_EXTEND_VECTOR_INREG:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
320 QueryType = Node->getValueType(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
321 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
322 case ISD::FP_ROUND_INREG:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
323 QueryType = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
324 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
325 case ISD::SINT_TO_FP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 case ISD::UINT_TO_FP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327 QueryType = Node->getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
329 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
330
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
331 switch (TLI.getOperationAction(Node->getOpcode(), QueryType)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
332 case TargetLowering::Promote:
|
77
|
333 Result = Promote(Op);
|
|
334 Changed = true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335 break;
|
77
|
336 case TargetLowering::Legal:
|
|
337 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
338 case TargetLowering::Custom: {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
339 SDValue Tmp1 = TLI.LowerOperation(Op, DAG);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340 if (Tmp1.getNode()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
341 Result = Tmp1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
342 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
343 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
344 // FALL THROUGH
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
345 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
346 case TargetLowering::Expand:
|
77
|
347 Result = Expand(Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
348 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
349
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
350 // Make sure that the generated code is itself legal.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 if (Result != Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
352 Result = LegalizeOp(Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
353 Changed = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
354 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
355
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
356 // Note that LegalizeOp may be reentered even from single-use nodes, which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
357 // means that we always must cache transformed nodes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
358 AddLegalizedOperand(Op, Result);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
359 return Result;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
360 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
361
|
77
|
362 SDValue VectorLegalizer::Promote(SDValue Op) {
|
|
363 // For a few operations there is a specific concept for promotion based on
|
|
364 // the operand's type.
|
|
365 switch (Op.getOpcode()) {
|
|
366 case ISD::SINT_TO_FP:
|
|
367 case ISD::UINT_TO_FP:
|
|
368 // "Promote" the operation by extending the operand.
|
|
369 return PromoteINT_TO_FP(Op);
|
|
370 case ISD::FP_TO_UINT:
|
|
371 case ISD::FP_TO_SINT:
|
|
372 // Promote the operation by extending the operand.
|
|
373 return PromoteFP_TO_INT(Op, Op->getOpcode() == ISD::FP_TO_SINT);
|
|
374 }
|
|
375
|
|
376 // There are currently two cases of vector promotion:
|
|
377 // 1) Bitcasting a vector of integers to a different type to a vector of the
|
|
378 // same overall length. For example, x86 promotes ISD::AND on v2i32 to v1i64.
|
|
379 // 2) Extending a vector of floats to a vector of the same number oflarger
|
|
380 // floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 MVT VT = Op.getSimpleValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 assert(Op.getNode()->getNumValues() == 1 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383 "Can't promote a vector with multiple results!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
384 MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
385 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
386 SmallVector<SDValue, 4> Operands(Op.getNumOperands());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
387
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
388 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
389 if (Op.getOperand(j).getValueType().isVector())
|
77
|
390 if (Op.getOperand(j)
|
|
391 .getValueType()
|
|
392 .getVectorElementType()
|
83
|
393 .isFloatingPoint() &&
|
|
394 NVT.isVector() && NVT.getVectorElementType().isFloatingPoint())
|
77
|
395 Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op.getOperand(j));
|
|
396 else
|
|
397 Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399 Operands[j] = Op.getOperand(j);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
400 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401
|
77
|
402 Op = DAG.getNode(Op.getOpcode(), dl, NVT, Operands);
|
83
|
403 if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
|
|
404 (VT.isVector() && VT.getVectorElementType().isFloatingPoint() &&
|
|
405 NVT.isVector() && NVT.getVectorElementType().isFloatingPoint()))
|
77
|
406 return DAG.getNode(ISD::FP_ROUND, dl, VT, Op, DAG.getIntPtrConstant(0));
|
|
407 else
|
|
408 return DAG.getNode(ISD::BITCAST, dl, VT, Op);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410
|
77
|
411 SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
412 // INT_TO_FP operations may require the input operand be promoted even
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413 // when the type is otherwise legal.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414 EVT VT = Op.getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
415 assert(Op.getNode()->getNumValues() == 1 &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
416 "Can't promote a vector with multiple results!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
417
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
418 // Normal getTypeToPromoteTo() doesn't work here, as that will promote
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
419 // by widening the vector w/ the same element width and twice the number
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
420 // of elements. We want the other way around, the same number of elements,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
421 // each twice the width.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
422 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
423 // Increase the bitwidth of the element to the next pow-of-two
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
424 // (which is greater than 8 bits).
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
425
|
77
|
426 EVT NVT = VT.widenIntegerVectorElementType(*DAG.getContext());
|
|
427 assert(NVT.isSimple() && "Promoting to a non-simple vector type!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
428 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
429 SmallVector<SDValue, 4> Operands(Op.getNumOperands());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
430
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
431 unsigned Opc = Op.getOpcode() == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND :
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
432 ISD::SIGN_EXTEND;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
433 for (unsigned j = 0; j != Op.getNumOperands(); ++j) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
434 if (Op.getOperand(j).getValueType().isVector())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
435 Operands[j] = DAG.getNode(Opc, dl, NVT, Op.getOperand(j));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
436 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
437 Operands[j] = Op.getOperand(j);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
438 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
439
|
77
|
440 return DAG.getNode(Op.getOpcode(), dl, Op.getValueType(), Operands);
|
|
441 }
|
|
442
|
|
443 // For FP_TO_INT we promote the result type to a vector type with wider
|
|
444 // elements and then truncate the result. This is different from the default
|
|
445 // PromoteVector which uses bitcast to promote thus assumning that the
|
|
446 // promoted vector type has the same overall size.
|
|
447 SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op, bool isSigned) {
|
|
448 assert(Op.getNode()->getNumValues() == 1 &&
|
|
449 "Can't promote a vector with multiple results!");
|
|
450 EVT VT = Op.getValueType();
|
|
451
|
|
452 EVT NewVT;
|
|
453 unsigned NewOpc;
|
|
454 while (1) {
|
|
455 NewVT = VT.widenIntegerVectorElementType(*DAG.getContext());
|
|
456 assert(NewVT.isSimple() && "Promoting to a non-simple vector type!");
|
|
457 if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewVT)) {
|
|
458 NewOpc = ISD::FP_TO_SINT;
|
|
459 break;
|
|
460 }
|
|
461 if (!isSigned && TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewVT)) {
|
|
462 NewOpc = ISD::FP_TO_UINT;
|
|
463 break;
|
|
464 }
|
|
465 }
|
|
466
|
|
467 SDLoc loc(Op);
|
|
468 SDValue promoted = DAG.getNode(NewOpc, SDLoc(Op), NewVT, Op.getOperand(0));
|
|
469 return DAG.getNode(ISD::TRUNCATE, SDLoc(Op), VT, promoted);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
470 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
471
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
472
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
473 SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
474 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
475 LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
476 SDValue Chain = LD->getChain();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
477 SDValue BasePTR = LD->getBasePtr();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
478 EVT SrcVT = LD->getMemoryVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
479 ISD::LoadExtType ExtType = LD->getExtensionType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
480
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
481 SmallVector<SDValue, 8> Vals;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
482 SmallVector<SDValue, 8> LoadChains;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
483 unsigned NumElem = SrcVT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
484
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
485 EVT SrcEltVT = SrcVT.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
486 EVT DstEltVT = Op.getNode()->getValueType(0).getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
487
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
488 if (SrcVT.getVectorNumElements() > 1 && !SrcEltVT.isByteSized()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
489 // When elements in a vector is not byte-addressable, we cannot directly
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
490 // load each element by advancing pointer, which could only address bytes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
491 // Instead, we load all significant words, mask bits off, and concatenate
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
492 // them to form each element. Finally, they are extended to destination
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
493 // scalar type to build the destination vector.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
494 EVT WideVT = TLI.getPointerTy();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
495
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
496 assert(WideVT.isRound() &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
497 "Could not handle the sophisticated case when the widest integer is"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
498 " not power of 2.");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
499 assert(WideVT.bitsGE(SrcEltVT) &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
500 "Type is not legalized?");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
501
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
502 unsigned WideBytes = WideVT.getStoreSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
503 unsigned Offset = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
504 unsigned RemainingBytes = SrcVT.getStoreSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
505 SmallVector<SDValue, 8> LoadVals;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
506
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
507 while (RemainingBytes > 0) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
508 SDValue ScalarLoad;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
509 unsigned LoadBytes = WideBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
510
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
511 if (RemainingBytes >= LoadBytes) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
512 ScalarLoad = DAG.getLoad(WideVT, dl, Chain, BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
513 LD->getPointerInfo().getWithOffset(Offset),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
514 LD->isVolatile(), LD->isNonTemporal(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
515 LD->isInvariant(), LD->getAlignment(),
|
77
|
516 LD->getAAInfo());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
517 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
518 EVT LoadVT = WideVT;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
519 while (RemainingBytes < LoadBytes) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
520 LoadBytes >>= 1; // Reduce the load size by half.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
521 LoadVT = EVT::getIntegerVT(*DAG.getContext(), LoadBytes << 3);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
522 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
523 ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, WideVT, Chain, BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
524 LD->getPointerInfo().getWithOffset(Offset),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
525 LoadVT, LD->isVolatile(),
|
77
|
526 LD->isNonTemporal(), LD->isInvariant(),
|
|
527 LD->getAlignment(), LD->getAAInfo());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
528 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
529
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
530 RemainingBytes -= LoadBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
531 Offset += LoadBytes;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
532 BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
533 DAG.getConstant(LoadBytes, BasePTR.getValueType()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
534
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
535 LoadVals.push_back(ScalarLoad.getValue(0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
536 LoadChains.push_back(ScalarLoad.getValue(1));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
537 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
538
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
539 // Extract bits, pack and extend/trunc them into destination type.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
540 unsigned SrcEltBits = SrcEltVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
541 SDValue SrcEltBitMask = DAG.getConstant((1U << SrcEltBits) - 1, WideVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
542
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
543 unsigned BitOffset = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
544 unsigned WideIdx = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
545 unsigned WideBits = WideVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
546
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
547 for (unsigned Idx = 0; Idx != NumElem; ++Idx) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
548 SDValue Lo, Hi, ShAmt;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
549
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
550 if (BitOffset < WideBits) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
551 ShAmt = DAG.getConstant(BitOffset, TLI.getShiftAmountTy(WideVT));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
552 Lo = DAG.getNode(ISD::SRL, dl, WideVT, LoadVals[WideIdx], ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
553 Lo = DAG.getNode(ISD::AND, dl, WideVT, Lo, SrcEltBitMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
554 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
555
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
556 BitOffset += SrcEltBits;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
557 if (BitOffset >= WideBits) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
558 WideIdx++;
|
83
|
559 BitOffset -= WideBits;
|
|
560 if (BitOffset > 0) {
|
|
561 ShAmt = DAG.getConstant(SrcEltBits - BitOffset,
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
562 TLI.getShiftAmountTy(WideVT));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
563 Hi = DAG.getNode(ISD::SHL, dl, WideVT, LoadVals[WideIdx], ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
564 Hi = DAG.getNode(ISD::AND, dl, WideVT, Hi, SrcEltBitMask);
|
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
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
568 if (Hi.getNode())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
569 Lo = DAG.getNode(ISD::OR, dl, WideVT, Lo, Hi);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
570
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
571 switch (ExtType) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
572 default: llvm_unreachable("Unknown extended-load op!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
573 case ISD::EXTLOAD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
574 Lo = DAG.getAnyExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
575 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
576 case ISD::ZEXTLOAD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
577 Lo = DAG.getZExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
578 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
579 case ISD::SEXTLOAD:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
580 ShAmt = DAG.getConstant(WideBits - SrcEltBits,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
581 TLI.getShiftAmountTy(WideVT));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
582 Lo = DAG.getNode(ISD::SHL, dl, WideVT, Lo, ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
583 Lo = DAG.getNode(ISD::SRA, dl, WideVT, Lo, ShAmt);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
584 Lo = DAG.getSExtOrTrunc(Lo, dl, DstEltVT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
585 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
586 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
587 Vals.push_back(Lo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
588 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
589 } else {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
590 unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
591
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
592 for (unsigned Idx=0; Idx<NumElem; Idx++) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
593 SDValue ScalarLoad = DAG.getExtLoad(ExtType, dl,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
594 Op.getNode()->getValueType(0).getScalarType(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
595 Chain, BasePTR, LD->getPointerInfo().getWithOffset(Idx * Stride),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
596 SrcVT.getScalarType(),
|
77
|
597 LD->isVolatile(), LD->isNonTemporal(), LD->isInvariant(),
|
|
598 LD->getAlignment(), LD->getAAInfo());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
599
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
600 BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
601 DAG.getConstant(Stride, BasePTR.getValueType()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
602
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
603 Vals.push_back(ScalarLoad.getValue(0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
604 LoadChains.push_back(ScalarLoad.getValue(1));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
605 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
606 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
607
|
77
|
608 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
609 SDValue Value = DAG.getNode(ISD::BUILD_VECTOR, dl,
|
77
|
610 Op.getNode()->getValueType(0), Vals);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
611
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
612 AddLegalizedOperand(Op.getValue(0), Value);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
613 AddLegalizedOperand(Op.getValue(1), NewChain);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
614
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
615 return (Op.getResNo() ? NewChain : Value);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
616 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
617
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
618 SDValue VectorLegalizer::ExpandStore(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
619 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
620 StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
621 SDValue Chain = ST->getChain();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
622 SDValue BasePTR = ST->getBasePtr();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
623 SDValue Value = ST->getValue();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
624 EVT StVT = ST->getMemoryVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
625
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
626 unsigned Alignment = ST->getAlignment();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
627 bool isVolatile = ST->isVolatile();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
628 bool isNonTemporal = ST->isNonTemporal();
|
77
|
629 AAMDNodes AAInfo = ST->getAAInfo();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
630
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
631 unsigned NumElem = StVT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
632 // The type of the data we want to save
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
633 EVT RegVT = Value.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
634 EVT RegSclVT = RegVT.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
635 // The type of data as saved in memory.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
636 EVT MemSclVT = StVT.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
637
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
638 // Cast floats into integers
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
639 unsigned ScalarSize = MemSclVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
640
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
641 // Round odd types to the next pow of two.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
642 if (!isPowerOf2_32(ScalarSize))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
643 ScalarSize = NextPowerOf2(ScalarSize);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
644
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
645 // Store Stride in bytes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
646 unsigned Stride = ScalarSize/8;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
647 // Extract each of the elements from the original vector
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
648 // and save them into memory individually.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
649 SmallVector<SDValue, 8> Stores;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
650 for (unsigned Idx = 0; Idx < NumElem; Idx++) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
651 SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
652 RegSclVT, Value, DAG.getConstant(Idx, TLI.getVectorIdxTy()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
653
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
654 // This scalar TruncStore may be illegal, but we legalize it later.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
655 SDValue Store = DAG.getTruncStore(Chain, dl, Ex, BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
656 ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT,
|
77
|
657 isVolatile, isNonTemporal, Alignment, AAInfo);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
658
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
659 BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
660 DAG.getConstant(Stride, BasePTR.getValueType()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
661
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
662 Stores.push_back(Store);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
663 }
|
77
|
664 SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Stores);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
665 AddLegalizedOperand(Op, TF);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
666 return TF;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
667 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
668
|
77
|
669 SDValue VectorLegalizer::Expand(SDValue Op) {
|
|
670 switch (Op->getOpcode()) {
|
|
671 case ISD::SIGN_EXTEND_INREG:
|
|
672 return ExpandSEXTINREG(Op);
|
|
673 case ISD::ANY_EXTEND_VECTOR_INREG:
|
|
674 return ExpandANY_EXTEND_VECTOR_INREG(Op);
|
|
675 case ISD::SIGN_EXTEND_VECTOR_INREG:
|
|
676 return ExpandSIGN_EXTEND_VECTOR_INREG(Op);
|
|
677 case ISD::ZERO_EXTEND_VECTOR_INREG:
|
|
678 return ExpandZERO_EXTEND_VECTOR_INREG(Op);
|
|
679 case ISD::BSWAP:
|
|
680 return ExpandBSWAP(Op);
|
|
681 case ISD::VSELECT:
|
|
682 return ExpandVSELECT(Op);
|
|
683 case ISD::SELECT:
|
|
684 return ExpandSELECT(Op);
|
|
685 case ISD::UINT_TO_FP:
|
|
686 return ExpandUINT_TO_FLOAT(Op);
|
|
687 case ISD::FNEG:
|
|
688 return ExpandFNEG(Op);
|
|
689 case ISD::SETCC:
|
|
690 return UnrollVSETCC(Op);
|
|
691 default:
|
|
692 return DAG.UnrollVectorOp(Op.getNode());
|
|
693 }
|
|
694 }
|
|
695
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
696 SDValue VectorLegalizer::ExpandSELECT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
697 // Lower a select instruction where the condition is a scalar and the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
698 // operands are vectors. Lower this select to VSELECT and implement it
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
699 // using XOR AND OR. The selector bit is broadcasted.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
700 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
701 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
702
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
703 SDValue Mask = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
704 SDValue Op1 = Op.getOperand(1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
705 SDValue Op2 = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
706
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
707 assert(VT.isVector() && !Mask.getValueType().isVector()
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
708 && Op1.getValueType() == Op2.getValueType() && "Invalid type");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
709
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
710 unsigned NumElem = VT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
711
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
712 // If we can't even use the basic vector operations of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
713 // AND,OR,XOR, we will have to scalarize the op.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
714 // Notice that the operation may be 'promoted' which means that it is
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
715 // 'bitcasted' to another type which is handled.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
716 // 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
|
717 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
718 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
719 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
720 TLI.getOperationAction(ISD::BUILD_VECTOR, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
721 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
722
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
723 // Generate a mask operand.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
724 EVT MaskTy = VT.changeVectorElementTypeToInteger();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
725
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
726 // What is the size of each element in the vector mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
727 EVT BitTy = MaskTy.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
728
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
729 Mask = DAG.getSelect(DL, BitTy, Mask,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
730 DAG.getConstant(APInt::getAllOnesValue(BitTy.getSizeInBits()), BitTy),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
731 DAG.getConstant(0, BitTy));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
732
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
733 // 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
|
734 SmallVector<SDValue, 8> Ops(NumElem, Mask);
|
77
|
735 Mask = DAG.getNode(ISD::BUILD_VECTOR, DL, MaskTy, Ops);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
736
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
737 // Bitcast the operands to be the same type as the mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
738 // This is needed when we select between FP types because
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
739 // the mask is a vector of integers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
740 Op1 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
741 Op2 = DAG.getNode(ISD::BITCAST, DL, MaskTy, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
742
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
743 SDValue AllOnes = DAG.getConstant(
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
744 APInt::getAllOnesValue(BitTy.getSizeInBits()), MaskTy);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
745 SDValue NotMask = DAG.getNode(ISD::XOR, DL, MaskTy, Mask, AllOnes);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
746
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
747 Op1 = DAG.getNode(ISD::AND, DL, MaskTy, Op1, Mask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
748 Op2 = DAG.getNode(ISD::AND, DL, MaskTy, Op2, NotMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
749 SDValue Val = DAG.getNode(ISD::OR, DL, MaskTy, Op1, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
750 return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
751 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
752
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
753 SDValue VectorLegalizer::ExpandSEXTINREG(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
754 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
755
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
756 // Make sure that the SRA and SHL instructions are available.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
757 if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
758 TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
759 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
760
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
761 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
762 EVT OrigTy = cast<VTSDNode>(Op->getOperand(1))->getVT();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
763
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
764 unsigned BW = VT.getScalarType().getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
765 unsigned OrigBW = OrigTy.getScalarType().getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
766 SDValue ShiftSz = DAG.getConstant(BW - OrigBW, VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
767
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
768 Op = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
769 Op = DAG.getNode(ISD::SHL, DL, VT, Op, ShiftSz);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
770 return DAG.getNode(ISD::SRA, DL, VT, Op, ShiftSz);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
771 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
772
|
77
|
773 // Generically expand a vector anyext in register to a shuffle of the relevant
|
|
774 // lanes into the appropriate locations, with other lanes left undef.
|
|
775 SDValue VectorLegalizer::ExpandANY_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
776 SDLoc DL(Op);
|
|
777 EVT VT = Op.getValueType();
|
|
778 int NumElements = VT.getVectorNumElements();
|
|
779 SDValue Src = Op.getOperand(0);
|
|
780 EVT SrcVT = Src.getValueType();
|
|
781 int NumSrcElements = SrcVT.getVectorNumElements();
|
|
782
|
|
783 // Build a base mask of undef shuffles.
|
|
784 SmallVector<int, 16> ShuffleMask;
|
|
785 ShuffleMask.resize(NumSrcElements, -1);
|
|
786
|
|
787 // Place the extended lanes into the correct locations.
|
|
788 int ExtLaneScale = NumSrcElements / NumElements;
|
|
789 int EndianOffset = TLI.isBigEndian() ? ExtLaneScale - 1 : 0;
|
|
790 for (int i = 0; i < NumElements; ++i)
|
|
791 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
|
|
792
|
|
793 return DAG.getNode(
|
|
794 ISD::BITCAST, DL, VT,
|
|
795 DAG.getVectorShuffle(SrcVT, DL, Src, DAG.getUNDEF(SrcVT), ShuffleMask));
|
|
796 }
|
|
797
|
|
798 SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
799 SDLoc DL(Op);
|
|
800 EVT VT = Op.getValueType();
|
|
801 SDValue Src = Op.getOperand(0);
|
|
802 EVT SrcVT = Src.getValueType();
|
|
803
|
|
804 // First build an any-extend node which can be legalized above when we
|
|
805 // recurse through it.
|
|
806 Op = DAG.getAnyExtendVectorInReg(Src, DL, VT);
|
|
807
|
|
808 // Now we need sign extend. Do this by shifting the elements. Even if these
|
|
809 // aren't legal operations, they have a better chance of being legalized
|
|
810 // without full scalarization than the sign extension does.
|
|
811 unsigned EltWidth = VT.getVectorElementType().getSizeInBits();
|
|
812 unsigned SrcEltWidth = SrcVT.getVectorElementType().getSizeInBits();
|
|
813 SDValue ShiftAmount = DAG.getConstant(EltWidth - SrcEltWidth, VT);
|
|
814 return DAG.getNode(ISD::SRA, DL, VT,
|
|
815 DAG.getNode(ISD::SHL, DL, VT, Op, ShiftAmount),
|
|
816 ShiftAmount);
|
|
817 }
|
|
818
|
|
819 // Generically expand a vector zext in register to a shuffle of the relevant
|
|
820 // lanes into the appropriate locations, a blend of zero into the high bits,
|
|
821 // and a bitcast to the wider element type.
|
|
822 SDValue VectorLegalizer::ExpandZERO_EXTEND_VECTOR_INREG(SDValue Op) {
|
|
823 SDLoc DL(Op);
|
|
824 EVT VT = Op.getValueType();
|
|
825 int NumElements = VT.getVectorNumElements();
|
|
826 SDValue Src = Op.getOperand(0);
|
|
827 EVT SrcVT = Src.getValueType();
|
|
828 int NumSrcElements = SrcVT.getVectorNumElements();
|
|
829
|
|
830 // Build up a zero vector to blend into this one.
|
|
831 EVT SrcScalarVT = SrcVT.getScalarType();
|
|
832 SDValue ScalarZero = DAG.getTargetConstant(0, SrcScalarVT);
|
|
833 SmallVector<SDValue, 4> BuildVectorOperands(NumSrcElements, ScalarZero);
|
|
834 SDValue Zero = DAG.getNode(ISD::BUILD_VECTOR, DL, SrcVT, BuildVectorOperands);
|
|
835
|
|
836 // Shuffle the incoming lanes into the correct position, and pull all other
|
|
837 // lanes from the zero vector.
|
|
838 SmallVector<int, 16> ShuffleMask;
|
|
839 ShuffleMask.reserve(NumSrcElements);
|
|
840 for (int i = 0; i < NumSrcElements; ++i)
|
|
841 ShuffleMask.push_back(i);
|
|
842
|
|
843 int ExtLaneScale = NumSrcElements / NumElements;
|
|
844 int EndianOffset = TLI.isBigEndian() ? ExtLaneScale - 1 : 0;
|
|
845 for (int i = 0; i < NumElements; ++i)
|
|
846 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
|
|
847
|
|
848 return DAG.getNode(ISD::BITCAST, DL, VT,
|
|
849 DAG.getVectorShuffle(SrcVT, DL, Zero, Src, ShuffleMask));
|
|
850 }
|
|
851
|
|
852 SDValue VectorLegalizer::ExpandBSWAP(SDValue Op) {
|
|
853 EVT VT = Op.getValueType();
|
|
854
|
|
855 // Generate a byte wise shuffle mask for the BSWAP.
|
|
856 SmallVector<int, 16> ShuffleMask;
|
|
857 int ScalarSizeInBytes = VT.getScalarSizeInBits() / 8;
|
|
858 for (int I = 0, E = VT.getVectorNumElements(); I != E; ++I)
|
|
859 for (int J = ScalarSizeInBytes - 1; J >= 0; --J)
|
|
860 ShuffleMask.push_back((I * ScalarSizeInBytes) + J);
|
|
861
|
|
862 EVT ByteVT = EVT::getVectorVT(*DAG.getContext(), MVT::i8, ShuffleMask.size());
|
|
863
|
|
864 // Only emit a shuffle if the mask is legal.
|
|
865 if (!TLI.isShuffleMaskLegal(ShuffleMask, ByteVT))
|
|
866 return DAG.UnrollVectorOp(Op.getNode());
|
|
867
|
|
868 SDLoc DL(Op);
|
|
869 Op = DAG.getNode(ISD::BITCAST, DL, ByteVT, Op.getOperand(0));
|
|
870 Op = DAG.getVectorShuffle(ByteVT, DL, Op, DAG.getUNDEF(ByteVT),
|
|
871 ShuffleMask.data());
|
|
872 return DAG.getNode(ISD::BITCAST, DL, VT, Op);
|
|
873 }
|
|
874
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
875 SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
876 // Implement VSELECT in terms of XOR, AND, OR
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
877 // on platforms which do not support blend natively.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
878 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
879
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
880 SDValue Mask = Op.getOperand(0);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
881 SDValue Op1 = Op.getOperand(1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
882 SDValue Op2 = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
883
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
884 EVT VT = Mask.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
885
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
886 // If we can't even use the basic vector operations of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
887 // AND,OR,XOR, we will have to scalarize the op.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
888 // Notice that the operation may be 'promoted' which means that it is
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
889 // 'bitcasted' to another type which is handled.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
890 // This operation also isn't safe with AND, OR, XOR when the boolean
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
891 // 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
|
892 // FIXME: Sign extend 1 to all ones if thats legal on the target.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
893 if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
894 TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
|
77
|
895 TLI.getOperationAction(ISD::OR, VT) == TargetLowering::Expand ||
|
|
896 TLI.getBooleanContents(Op1.getValueType()) !=
|
|
897 TargetLowering::ZeroOrNegativeOneBooleanContent)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
898 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
899
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
900 // 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
|
901 // can occur when getSetCCResultType returns something that is different in
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
902 // size from the operand types. For example, v4i8 = select v4i32, v4i8, v4i8.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
903 if (VT.getSizeInBits() != Op1.getValueType().getSizeInBits())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
904 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
905
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
906 // Bitcast the operands to be the same type as the mask.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
907 // This is needed when we select between FP types because
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
908 // the mask is a vector of integers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
909 Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
910 Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
911
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
912 SDValue AllOnes = DAG.getConstant(
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
913 APInt::getAllOnesValue(VT.getScalarType().getSizeInBits()), VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
914 SDValue NotMask = DAG.getNode(ISD::XOR, DL, VT, Mask, AllOnes);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
915
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
916 Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
917 Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
918 SDValue Val = DAG.getNode(ISD::OR, DL, VT, Op1, Op2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
919 return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
920 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
921
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
922 SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
923 EVT VT = Op.getOperand(0).getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
924 SDLoc DL(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
925
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
926 // Make sure that the SINT_TO_FP and SRL instructions are available.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
927 if (TLI.getOperationAction(ISD::SINT_TO_FP, VT) == TargetLowering::Expand ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
928 TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Expand)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
929 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
930
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
931 EVT SVT = VT.getScalarType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
932 assert((SVT.getSizeInBits() == 64 || SVT.getSizeInBits() == 32) &&
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
933 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
934
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
935 unsigned BW = SVT.getSizeInBits();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
936 SDValue HalfWord = DAG.getConstant(BW/2, VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
937
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
938 // Constants to clear the upper part of the word.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
939 // 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
|
940 // faster on x86.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
941 uint64_t HWMask = (SVT.getSizeInBits()==64)?0x00000000FFFFFFFF:0x0000FFFF;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
942 SDValue HalfWordMask = DAG.getConstant(HWMask, VT);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
943
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
944 // Two to the power of half-word-size.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
945 SDValue TWOHW = DAG.getConstantFP((1<<(BW/2)), Op.getValueType());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
946
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
947 // Clear upper part of LO, lower HI
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
948 SDValue HI = DAG.getNode(ISD::SRL, DL, VT, Op.getOperand(0), HalfWord);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
949 SDValue LO = DAG.getNode(ISD::AND, DL, VT, Op.getOperand(0), HalfWordMask);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
950
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
951 // Convert hi and lo to floats
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
952 // Convert the hi part back to the upper values
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
953 SDValue fHI = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), HI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
954 fHI = DAG.getNode(ISD::FMUL, DL, Op.getValueType(), fHI, TWOHW);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
955 SDValue fLO = DAG.getNode(ISD::SINT_TO_FP, DL, Op.getValueType(), LO);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
956
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
957 // Add the two halves
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
958 return DAG.getNode(ISD::FADD, DL, Op.getValueType(), fHI, fLO);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
959 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
960
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
961
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
962 SDValue VectorLegalizer::ExpandFNEG(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
963 if (TLI.isOperationLegalOrCustom(ISD::FSUB, Op.getValueType())) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
964 SDValue Zero = DAG.getConstantFP(-0.0, Op.getValueType());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
965 return DAG.getNode(ISD::FSUB, SDLoc(Op), Op.getValueType(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
966 Zero, Op.getOperand(0));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
967 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
968 return DAG.UnrollVectorOp(Op.getNode());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
969 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
970
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
971 SDValue VectorLegalizer::UnrollVSETCC(SDValue Op) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
972 EVT VT = Op.getValueType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
973 unsigned NumElems = VT.getVectorNumElements();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
974 EVT EltVT = VT.getVectorElementType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
975 SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1), CC = Op.getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
976 EVT TmpEltVT = LHS.getValueType().getVectorElementType();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
977 SDLoc dl(Op);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
978 SmallVector<SDValue, 8> Ops(NumElems);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
979 for (unsigned i = 0; i < NumElems; ++i) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
980 SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
981 DAG.getConstant(i, TLI.getVectorIdxTy()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
982 SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
983 DAG.getConstant(i, TLI.getVectorIdxTy()));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
984 Ops[i] = DAG.getNode(ISD::SETCC, dl,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
985 TLI.getSetCCResultType(*DAG.getContext(), TmpEltVT),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
986 LHSElem, RHSElem, CC);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
987 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
988 DAG.getConstant(APInt::getAllOnesValue
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
989 (EltVT.getSizeInBits()), EltVT),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
990 DAG.getConstant(0, EltVT));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
991 }
|
77
|
992 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
993 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
994
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
995 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
996
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
997 bool SelectionDAG::LegalizeVectors() {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
998 return VectorLegalizer(*this).Run();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
999 }
|