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