R600: Add support for global vector stores with elements less than 32-bits
[oota-llvm.git] / lib / Target / R600 / AMDGPUISelLowering.cpp
1 //===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief This is the parent TargetLowering class for hardware code gen
12 /// targets.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "AMDGPUISelLowering.h"
17 #include "AMDGPU.h"
18 #include "AMDGPURegisterInfo.h"
19 #include "AMDGPUSubtarget.h"
20 #include "AMDILIntrinsicInfo.h"
21 #include "R600MachineFunctionInfo.h"
22 #include "SIMachineFunctionInfo.h"
23 #include "llvm/CodeGen/CallingConvLower.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/SelectionDAG.h"
27 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28 #include "llvm/IR/DataLayout.h"
29
30 using namespace llvm;
31
32 #include "AMDGPUGenCallingConv.inc"
33
34 AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
35   TargetLowering(TM, new TargetLoweringObjectFileELF()) {
36
37   // Initialize target lowering borrowed from AMDIL
38   InitAMDILLowering();
39
40   // We need to custom lower some of the intrinsics
41   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
42
43   // Library functions.  These default to Expand, but we have instructions
44   // for them.
45   setOperationAction(ISD::FCEIL,  MVT::f32, Legal);
46   setOperationAction(ISD::FEXP2,  MVT::f32, Legal);
47   setOperationAction(ISD::FPOW,   MVT::f32, Legal);
48   setOperationAction(ISD::FLOG2,  MVT::f32, Legal);
49   setOperationAction(ISD::FABS,   MVT::f32, Legal);
50   setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
51   setOperationAction(ISD::FRINT,  MVT::f32, Legal);
52
53   // The hardware supports ROTR, but not ROTL
54   setOperationAction(ISD::ROTL, MVT::i32, Expand);
55
56   // Lower floating point store/load to integer store/load to reduce the number
57   // of patterns in tablegen.
58   setOperationAction(ISD::STORE, MVT::f32, Promote);
59   AddPromotedToType(ISD::STORE, MVT::f32, MVT::i32);
60
61   setOperationAction(ISD::STORE, MVT::v2f32, Promote);
62   AddPromotedToType(ISD::STORE, MVT::v2f32, MVT::v2i32);
63
64   setOperationAction(ISD::STORE, MVT::v4f32, Promote);
65   AddPromotedToType(ISD::STORE, MVT::v4f32, MVT::v4i32);
66
67   setOperationAction(ISD::STORE, MVT::f64, Promote);
68   AddPromotedToType(ISD::STORE, MVT::f64, MVT::i64);
69
70   setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
71   setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
72   setTruncStoreAction(MVT::v4i32, MVT::v4i8, Custom);
73   // XXX: This can be change to Custom, once ExpandVectorStores can
74   // handle 64-bit stores.
75   setTruncStoreAction(MVT::v4i32, MVT::v4i16, Expand);
76
77   setOperationAction(ISD::LOAD, MVT::f32, Promote);
78   AddPromotedToType(ISD::LOAD, MVT::f32, MVT::i32);
79
80   setOperationAction(ISD::LOAD, MVT::v2f32, Promote);
81   AddPromotedToType(ISD::LOAD, MVT::v2f32, MVT::v2i32);
82
83   setOperationAction(ISD::LOAD, MVT::v4f32, Promote);
84   AddPromotedToType(ISD::LOAD, MVT::v4f32, MVT::v4i32);
85
86   setOperationAction(ISD::LOAD, MVT::f64, Promote);
87   AddPromotedToType(ISD::LOAD, MVT::f64, MVT::i64);
88
89   setOperationAction(ISD::CONCAT_VECTORS, MVT::v4i32, Custom);
90   setOperationAction(ISD::CONCAT_VECTORS, MVT::v4f32, Custom);
91   setOperationAction(ISD::EXTRACT_SUBVECTOR, MVT::v2i32, Custom);
92   setOperationAction(ISD::EXTRACT_SUBVECTOR, MVT::v2f32, Custom);
93
94   setOperationAction(ISD::FNEG, MVT::v2f32, Expand);
95   setOperationAction(ISD::FNEG, MVT::v4f32, Expand);
96
97   setOperationAction(ISD::MUL, MVT::i64, Expand);
98
99   setOperationAction(ISD::UDIV, MVT::i32, Expand);
100   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
101   setOperationAction(ISD::UREM, MVT::i32, Expand);
102   setOperationAction(ISD::VSELECT, MVT::v2f32, Expand);
103   setOperationAction(ISD::VSELECT, MVT::v4f32, Expand);
104
105   static const int types[] = {
106     (int)MVT::v2i32,
107     (int)MVT::v4i32
108   };
109   const size_t NumTypes = array_lengthof(types);
110
111   for (unsigned int x  = 0; x < NumTypes; ++x) {
112     MVT::SimpleValueType VT = (MVT::SimpleValueType)types[x];
113     //Expand the following operations for the current type by default
114     setOperationAction(ISD::ADD,  VT, Expand);
115     setOperationAction(ISD::AND,  VT, Expand);
116     setOperationAction(ISD::FP_TO_SINT, VT, Expand);
117     setOperationAction(ISD::FP_TO_UINT, VT, Expand);
118     setOperationAction(ISD::MUL,  VT, Expand);
119     setOperationAction(ISD::OR,   VT, Expand);
120     setOperationAction(ISD::SHL,  VT, Expand);
121     setOperationAction(ISD::SINT_TO_FP, VT, Expand);
122     setOperationAction(ISD::SRL,  VT, Expand);
123     setOperationAction(ISD::SRA,  VT, Expand);
124     setOperationAction(ISD::SUB,  VT, Expand);
125     setOperationAction(ISD::UDIV, VT, Expand);
126     setOperationAction(ISD::UINT_TO_FP, VT, Expand);
127     setOperationAction(ISD::UREM, VT, Expand);
128     setOperationAction(ISD::VSELECT, VT, Expand);
129     setOperationAction(ISD::XOR,  VT, Expand);
130   }
131 }
132
133 //===----------------------------------------------------------------------===//
134 // Target Information
135 //===----------------------------------------------------------------------===//
136
137 MVT AMDGPUTargetLowering::getVectorIdxTy() const {
138   return MVT::i32;
139 }
140
141
142 //===---------------------------------------------------------------------===//
143 // Target Properties
144 //===---------------------------------------------------------------------===//
145
146 bool AMDGPUTargetLowering::isFAbsFree(EVT VT) const {
147   assert(VT.isFloatingPoint());
148   return VT == MVT::f32;
149 }
150
151 bool AMDGPUTargetLowering::isFNegFree(EVT VT) const {
152   assert(VT.isFloatingPoint());
153   return VT == MVT::f32;
154 }
155
156 //===---------------------------------------------------------------------===//
157 // TargetLowering Callbacks
158 //===---------------------------------------------------------------------===//
159
160 void AMDGPUTargetLowering::AnalyzeFormalArguments(CCState &State,
161                              const SmallVectorImpl<ISD::InputArg> &Ins) const {
162
163   State.AnalyzeFormalArguments(Ins, CC_AMDGPU);
164 }
165
166 SDValue AMDGPUTargetLowering::LowerReturn(
167                                      SDValue Chain,
168                                      CallingConv::ID CallConv,
169                                      bool isVarArg,
170                                      const SmallVectorImpl<ISD::OutputArg> &Outs,
171                                      const SmallVectorImpl<SDValue> &OutVals,
172                                      SDLoc DL, SelectionDAG &DAG) const {
173   return DAG.getNode(AMDGPUISD::RET_FLAG, DL, MVT::Other, Chain);
174 }
175
176 //===---------------------------------------------------------------------===//
177 // Target specific lowering
178 //===---------------------------------------------------------------------===//
179
180 SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
181     const {
182   switch (Op.getOpcode()) {
183   default:
184     Op.getNode()->dump();
185     assert(0 && "Custom lowering code for this"
186         "instruction is not implemented yet!");
187     break;
188   // AMDIL DAG lowering
189   case ISD::SDIV: return LowerSDIV(Op, DAG);
190   case ISD::SREM: return LowerSREM(Op, DAG);
191   case ISD::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
192   case ISD::BRCOND: return LowerBRCOND(Op, DAG);
193   // AMDGPU DAG lowering
194   case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
195   case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
196   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
197   case ISD::STORE: return LowerVectorStore(Op, DAG);
198   case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
199   }
200   return Op;
201 }
202
203 SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
204                                                  SDValue Op,
205                                                  SelectionDAG &DAG) const {
206
207   const DataLayout *TD = getTargetMachine().getDataLayout();
208   GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
209   // XXX: What does the value of G->getOffset() mean?
210   assert(G->getOffset() == 0 &&
211          "Do not know what to do with an non-zero offset");
212
213   unsigned Offset = MFI->LDSSize;
214   const GlobalValue *GV = G->getGlobal();
215   uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
216
217   // XXX: Account for alignment?
218   MFI->LDSSize += Size;
219
220   return DAG.getConstant(Offset, TD->getPointerSize() == 8 ? MVT::i64 : MVT::i32);
221 }
222
223 void AMDGPUTargetLowering::ExtractVectorElements(SDValue Op, SelectionDAG &DAG,
224                                          SmallVectorImpl<SDValue> &Args,
225                                          unsigned Start,
226                                          unsigned Count) const {
227   EVT VT = Op.getValueType();
228   for (unsigned i = Start, e = Start + Count; i != e; ++i) {
229     Args.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
230                                VT.getVectorElementType(),
231                                Op, DAG.getConstant(i, MVT::i32)));
232   }
233 }
234
235 SDValue AMDGPUTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
236                                                   SelectionDAG &DAG) const {
237   SmallVector<SDValue, 8> Args;
238   SDValue A = Op.getOperand(0);
239   SDValue B = Op.getOperand(1);
240
241   ExtractVectorElements(A, DAG, Args, 0,
242                         A.getValueType().getVectorNumElements());
243   ExtractVectorElements(B, DAG, Args, 0,
244                         B.getValueType().getVectorNumElements());
245
246   return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(Op), Op.getValueType(),
247                      &Args[0], Args.size());
248 }
249
250 SDValue AMDGPUTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
251                                                      SelectionDAG &DAG) const {
252
253   SmallVector<SDValue, 8> Args;
254   EVT VT = Op.getValueType();
255   unsigned Start = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
256   ExtractVectorElements(Op.getOperand(0), DAG, Args, Start,
257                         VT.getVectorNumElements());
258
259   return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(Op), Op.getValueType(),
260                      &Args[0], Args.size());
261 }
262
263
264 SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
265     SelectionDAG &DAG) const {
266   unsigned IntrinsicID = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
267   SDLoc DL(Op);
268   EVT VT = Op.getValueType();
269
270   switch (IntrinsicID) {
271     default: return Op;
272     case AMDGPUIntrinsic::AMDIL_abs:
273       return LowerIntrinsicIABS(Op, DAG);
274     case AMDGPUIntrinsic::AMDIL_exp:
275       return DAG.getNode(ISD::FEXP2, DL, VT, Op.getOperand(1));
276     case AMDGPUIntrinsic::AMDGPU_lrp:
277       return LowerIntrinsicLRP(Op, DAG);
278     case AMDGPUIntrinsic::AMDIL_fraction:
279       return DAG.getNode(AMDGPUISD::FRACT, DL, VT, Op.getOperand(1));
280     case AMDGPUIntrinsic::AMDIL_max:
281       return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
282                                                   Op.getOperand(2));
283     case AMDGPUIntrinsic::AMDGPU_imax:
284       return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
285                                                   Op.getOperand(2));
286     case AMDGPUIntrinsic::AMDGPU_umax:
287       return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
288                                                   Op.getOperand(2));
289     case AMDGPUIntrinsic::AMDIL_min:
290       return DAG.getNode(AMDGPUISD::FMIN, DL, VT, Op.getOperand(1),
291                                                   Op.getOperand(2));
292     case AMDGPUIntrinsic::AMDGPU_imin:
293       return DAG.getNode(AMDGPUISD::SMIN, DL, VT, Op.getOperand(1),
294                                                   Op.getOperand(2));
295     case AMDGPUIntrinsic::AMDGPU_umin:
296       return DAG.getNode(AMDGPUISD::UMIN, DL, VT, Op.getOperand(1),
297                                                   Op.getOperand(2));
298     case AMDGPUIntrinsic::AMDIL_round_nearest:
299       return DAG.getNode(ISD::FRINT, DL, VT, Op.getOperand(1));
300   }
301 }
302
303 ///IABS(a) = SMAX(sub(0, a), a)
304 SDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
305     SelectionDAG &DAG) const {
306
307   SDLoc DL(Op);
308   EVT VT = Op.getValueType();
309   SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
310                                               Op.getOperand(1));
311
312   return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
313 }
314
315 /// Linear Interpolation
316 /// LRP(a, b, c) = muladd(a,  b, (1 - a) * c)
317 SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
318     SelectionDAG &DAG) const {
319   SDLoc DL(Op);
320   EVT VT = Op.getValueType();
321   SDValue OneSubA = DAG.getNode(ISD::FSUB, DL, VT,
322                                 DAG.getConstantFP(1.0f, MVT::f32),
323                                 Op.getOperand(1));
324   SDValue OneSubAC = DAG.getNode(ISD::FMUL, DL, VT, OneSubA,
325                                                     Op.getOperand(3));
326   return DAG.getNode(ISD::FADD, DL, VT,
327       DAG.getNode(ISD::FMUL, DL, VT, Op.getOperand(1), Op.getOperand(2)),
328       OneSubAC);
329 }
330
331 /// \brief Generate Min/Max node
332 SDValue AMDGPUTargetLowering::LowerMinMax(SDValue Op,
333     SelectionDAG &DAG) const {
334   SDLoc DL(Op);
335   EVT VT = Op.getValueType();
336
337   SDValue LHS = Op.getOperand(0);
338   SDValue RHS = Op.getOperand(1);
339   SDValue True = Op.getOperand(2);
340   SDValue False = Op.getOperand(3);
341   SDValue CC = Op.getOperand(4);
342
343   if (VT != MVT::f32 ||
344       !((LHS == True && RHS == False) || (LHS == False && RHS == True))) {
345     return SDValue();
346   }
347
348   ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
349   switch (CCOpcode) {
350   case ISD::SETOEQ:
351   case ISD::SETONE:
352   case ISD::SETUNE:
353   case ISD::SETNE:
354   case ISD::SETUEQ:
355   case ISD::SETEQ:
356   case ISD::SETFALSE:
357   case ISD::SETFALSE2:
358   case ISD::SETTRUE:
359   case ISD::SETTRUE2:
360   case ISD::SETUO:
361   case ISD::SETO:
362     assert(0 && "Operation should already be optimised !");
363   case ISD::SETULE:
364   case ISD::SETULT:
365   case ISD::SETOLE:
366   case ISD::SETOLT:
367   case ISD::SETLE:
368   case ISD::SETLT: {
369     if (LHS == True)
370       return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
371     else
372       return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
373   }
374   case ISD::SETGT:
375   case ISD::SETGE:
376   case ISD::SETUGE:
377   case ISD::SETOGE:
378   case ISD::SETUGT:
379   case ISD::SETOGT: {
380     if (LHS == True)
381       return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
382     else
383       return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
384   }
385   case ISD::SETCC_INVALID:
386     assert(0 && "Invalid setcc condcode !");
387   }
388   return Op;
389 }
390
391
392
393 SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
394     SelectionDAG &DAG) const {
395   SDLoc DL(Op);
396   EVT VT = Op.getValueType();
397
398   SDValue Num = Op.getOperand(0);
399   SDValue Den = Op.getOperand(1);
400
401   SmallVector<SDValue, 8> Results;
402
403   // RCP =  URECIP(Den) = 2^32 / Den + e
404   // e is rounding error.
405   SDValue RCP = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Den);
406
407   // RCP_LO = umulo(RCP, Den) */
408   SDValue RCP_LO = DAG.getNode(ISD::UMULO, DL, VT, RCP, Den);
409
410   // RCP_HI = mulhu (RCP, Den) */
411   SDValue RCP_HI = DAG.getNode(ISD::MULHU, DL, VT, RCP, Den);
412
413   // NEG_RCP_LO = -RCP_LO
414   SDValue NEG_RCP_LO = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
415                                                      RCP_LO);
416
417   // ABS_RCP_LO = (RCP_HI == 0 ? NEG_RCP_LO : RCP_LO)
418   SDValue ABS_RCP_LO = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
419                                            NEG_RCP_LO, RCP_LO,
420                                            ISD::SETEQ);
421   // Calculate the rounding error from the URECIP instruction
422   // E = mulhu(ABS_RCP_LO, RCP)
423   SDValue E = DAG.getNode(ISD::MULHU, DL, VT, ABS_RCP_LO, RCP);
424
425   // RCP_A_E = RCP + E
426   SDValue RCP_A_E = DAG.getNode(ISD::ADD, DL, VT, RCP, E);
427
428   // RCP_S_E = RCP - E
429   SDValue RCP_S_E = DAG.getNode(ISD::SUB, DL, VT, RCP, E);
430
431   // Tmp0 = (RCP_HI == 0 ? RCP_A_E : RCP_SUB_E)
432   SDValue Tmp0 = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
433                                      RCP_A_E, RCP_S_E,
434                                      ISD::SETEQ);
435   // Quotient = mulhu(Tmp0, Num)
436   SDValue Quotient = DAG.getNode(ISD::MULHU, DL, VT, Tmp0, Num);
437
438   // Num_S_Remainder = Quotient * Den
439   SDValue Num_S_Remainder = DAG.getNode(ISD::UMULO, DL, VT, Quotient, Den);
440
441   // Remainder = Num - Num_S_Remainder
442   SDValue Remainder = DAG.getNode(ISD::SUB, DL, VT, Num, Num_S_Remainder);
443
444   // Remainder_GE_Den = (Remainder >= Den ? -1 : 0)
445   SDValue Remainder_GE_Den = DAG.getSelectCC(DL, Remainder, Den,
446                                                  DAG.getConstant(-1, VT),
447                                                  DAG.getConstant(0, VT),
448                                                  ISD::SETGE);
449   // Remainder_GE_Zero = (Remainder >= 0 ? -1 : 0)
450   SDValue Remainder_GE_Zero = DAG.getSelectCC(DL, Remainder,
451                                                   DAG.getConstant(0, VT),
452                                                   DAG.getConstant(-1, VT),
453                                                   DAG.getConstant(0, VT),
454                                                   ISD::SETGE);
455   // Tmp1 = Remainder_GE_Den & Remainder_GE_Zero
456   SDValue Tmp1 = DAG.getNode(ISD::AND, DL, VT, Remainder_GE_Den,
457                                                Remainder_GE_Zero);
458
459   // Calculate Division result:
460
461   // Quotient_A_One = Quotient + 1
462   SDValue Quotient_A_One = DAG.getNode(ISD::ADD, DL, VT, Quotient,
463                                                          DAG.getConstant(1, VT));
464
465   // Quotient_S_One = Quotient - 1
466   SDValue Quotient_S_One = DAG.getNode(ISD::SUB, DL, VT, Quotient,
467                                                          DAG.getConstant(1, VT));
468
469   // Div = (Tmp1 == 0 ? Quotient : Quotient_A_One)
470   SDValue Div = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
471                                      Quotient, Quotient_A_One, ISD::SETEQ);
472
473   // Div = (Remainder_GE_Zero == 0 ? Quotient_S_One : Div)
474   Div = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
475                             Quotient_S_One, Div, ISD::SETEQ);
476
477   // Calculate Rem result:
478
479   // Remainder_S_Den = Remainder - Den
480   SDValue Remainder_S_Den = DAG.getNode(ISD::SUB, DL, VT, Remainder, Den);
481
482   // Remainder_A_Den = Remainder + Den
483   SDValue Remainder_A_Den = DAG.getNode(ISD::ADD, DL, VT, Remainder, Den);
484
485   // Rem = (Tmp1 == 0 ? Remainder : Remainder_S_Den)
486   SDValue Rem = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
487                                     Remainder, Remainder_S_Den, ISD::SETEQ);
488
489   // Rem = (Remainder_GE_Zero == 0 ? Remainder_A_Den : Rem)
490   Rem = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
491                             Remainder_A_Den, Rem, ISD::SETEQ);
492   SDValue Ops[2];
493   Ops[0] = Div;
494   Ops[1] = Rem;
495   return DAG.getMergeValues(Ops, 2, DL);
496 }
497
498 SDValue AMDGPUTargetLowering::LowerVectorStore(const SDValue &Op,
499                                                SelectionDAG &DAG) const {
500   StoreSDNode *Store = dyn_cast<StoreSDNode>(Op);
501   EVT MemVT = Store->getMemoryVT();
502   unsigned MemBits = MemVT.getSizeInBits();
503
504   // Byte stores are really expensive, so if possible, try to pack
505   // 32-bit vector truncatating store into an i32 store.
506   // XXX: We could also handle optimize other vector bitwidths
507   if (!MemVT.isVector() || MemBits > 32) {
508     return SDValue();
509   }
510
511   SDLoc DL(Op);
512   const SDValue &Value = Store->getValue();
513   EVT VT = Value.getValueType();
514   const SDValue &Ptr = Store->getBasePtr();
515   EVT MemEltVT = MemVT.getVectorElementType();
516   unsigned MemEltBits = MemEltVT.getSizeInBits();
517   unsigned MemNumElements = MemVT.getVectorNumElements();
518   EVT PackedVT = EVT::getIntegerVT(*DAG.getContext(), MemVT.getSizeInBits());
519   SDValue Mask;
520   switch(MemEltBits) {
521   case 8:
522     Mask = DAG.getConstant(0xFF, PackedVT);
523     break;
524   case 16:
525     Mask = DAG.getConstant(0xFFFF, PackedVT);
526     break;
527   default:
528     llvm_unreachable("Cannot lower this vector store");
529   }
530   SDValue PackedValue;
531   for (unsigned i = 0; i < MemNumElements; ++i) {
532     EVT ElemVT = VT.getVectorElementType();
533     SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT, Value,
534                               DAG.getConstant(i, MVT::i32));
535     Elt = DAG.getZExtOrTrunc(Elt, DL, PackedVT);
536     Elt = DAG.getNode(ISD::AND, DL, PackedVT, Elt, Mask);
537     SDValue Shift = DAG.getConstant(MemEltBits * i, PackedVT);
538     Elt = DAG.getNode(ISD::SHL, DL, PackedVT, Elt, Shift);
539     if (i == 0) {
540       PackedValue = Elt;
541     } else {
542       PackedValue = DAG.getNode(ISD::OR, DL, PackedVT, PackedValue, Elt);
543     }
544   }
545   return DAG.getStore(Store->getChain(), DL, PackedValue, Ptr,
546                       MachinePointerInfo(Store->getMemOperand()->getValue()),
547                       Store->isVolatile(),  Store->isNonTemporal(),
548                       Store->getAlignment());
549 }
550
551 //===----------------------------------------------------------------------===//
552 // Helper functions
553 //===----------------------------------------------------------------------===//
554
555 bool AMDGPUTargetLowering::isHWTrueValue(SDValue Op) const {
556   if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
557     return CFP->isExactlyValue(1.0);
558   }
559   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
560     return C->isAllOnesValue();
561   }
562   return false;
563 }
564
565 bool AMDGPUTargetLowering::isHWFalseValue(SDValue Op) const {
566   if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
567     return CFP->getValueAPF().isZero();
568   }
569   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
570     return C->isNullValue();
571   }
572   return false;
573 }
574
575 SDValue AMDGPUTargetLowering::CreateLiveInRegister(SelectionDAG &DAG,
576                                                   const TargetRegisterClass *RC,
577                                                    unsigned Reg, EVT VT) const {
578   MachineFunction &MF = DAG.getMachineFunction();
579   MachineRegisterInfo &MRI = MF.getRegInfo();
580   unsigned VirtualRegister;
581   if (!MRI.isLiveIn(Reg)) {
582     VirtualRegister = MRI.createVirtualRegister(RC);
583     MRI.addLiveIn(Reg, VirtualRegister);
584   } else {
585     VirtualRegister = MRI.getLiveInVirtReg(Reg);
586   }
587   return DAG.getRegister(VirtualRegister, VT);
588 }
589
590 #define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
591
592 const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
593   switch (Opcode) {
594   default: return 0;
595   // AMDIL DAG nodes
596   NODE_NAME_CASE(CALL);
597   NODE_NAME_CASE(UMUL);
598   NODE_NAME_CASE(DIV_INF);
599   NODE_NAME_CASE(RET_FLAG);
600   NODE_NAME_CASE(BRANCH_COND);
601
602   // AMDGPU DAG nodes
603   NODE_NAME_CASE(DWORDADDR)
604   NODE_NAME_CASE(FRACT)
605   NODE_NAME_CASE(FMAX)
606   NODE_NAME_CASE(SMAX)
607   NODE_NAME_CASE(UMAX)
608   NODE_NAME_CASE(FMIN)
609   NODE_NAME_CASE(SMIN)
610   NODE_NAME_CASE(UMIN)
611   NODE_NAME_CASE(URECIP)
612   NODE_NAME_CASE(EXPORT)
613   NODE_NAME_CASE(CONST_ADDRESS)
614   NODE_NAME_CASE(REGISTER_LOAD)
615   NODE_NAME_CASE(REGISTER_STORE)
616   NODE_NAME_CASE(LOAD_CONSTANT)
617   NODE_NAME_CASE(LOAD_INPUT)
618   NODE_NAME_CASE(SAMPLE)
619   NODE_NAME_CASE(SAMPLEB)
620   NODE_NAME_CASE(SAMPLED)
621   NODE_NAME_CASE(SAMPLEL)
622   NODE_NAME_CASE(STORE_MSKOR)
623   }
624 }