Now that predicates can be composed, simplify several of
[oota-llvm.git] / lib / Target / TargetSelectionDAG.td
index bb67cbfbeffcfd6995ba854e270e53b27a5de09c..a9702482700238da6cb0419d409b24b12f3ee556 100644 (file)
@@ -2,8 +2,8 @@
 // 
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 // 
 //===----------------------------------------------------------------------===//
 //
@@ -52,14 +52,21 @@ class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{
 }
 
 /// SDTCisIntVectorOfSameSize - This indicates that ThisOp and OtherOp are
-/// packed vector types, and that ThisOp is the result of 
-/// MVT::getIntVectorWithNumElements with the number of elements that ThisOp
-/// has.
+/// vector types, and that ThisOp is the result of 
+/// MVT::getIntVectorWithNumElements with the number of elements
+/// that ThisOp has.
 class SDTCisIntVectorOfSameSize<int ThisOp, int OtherOp>
   : SDTypeConstraint<ThisOp> {
   int OtherOpNum = OtherOp;
 }
 
+/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
+/// type as the element type of OtherOp, which is a vector type.
+class SDTCisEltOfVec<int ThisOp, int OtherOp>
+  : SDTypeConstraint<ThisOp> {
+  int OtherOpNum = OtherOp;
+}
+
 //===----------------------------------------------------------------------===//
 // Selection DAG Type Profile definitions.
 //
@@ -154,7 +161,7 @@ def SDTBrind : SDTypeProfile<0, 1, [ // brind
   SDTCisPtrTy<0>
 ]>;
 
-def SDTRet : SDTypeProfile<0, 0, []>; // ret
+def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
 
 def SDTLoad : SDTypeProfile<1, 1, [ // load
   SDTCisPtrTy<1>  
@@ -164,9 +171,39 @@ def SDTStore : SDTypeProfile<0, 2, [ // store
   SDTCisPtrTy<1>  
 ]>;
 
+def SDTIStore : SDTypeProfile<1, 3, [ // indexed store
+  SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3>
+]>;
+
 def SDTVecShuffle : SDTypeProfile<1, 3, [
   SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisIntVectorOfSameSize<3, 0>
 ]>;
+def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract
+  SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2>
+]>;
+def SDTVecInsert : SDTypeProfile<1, 3, [  // vector insert
+  SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
+]>;
+
+def STDPrefetch : SDTypeProfile<0, 3, [  // prefetch
+  SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1>
+]>;
+
+def STDMemBarrier : SDTypeProfile<0, 5, [ // memory barier
+  SDTCisSameAs<0,1>,  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisSameAs<0,4>,
+  SDTCisInt<0>
+]>;
+def STDAtomic3 : SDTypeProfile<1, 3, [
+  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+def STDAtomic2 : SDTypeProfile<1, 2, [
+  SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+
+class SDCallSeqStart<list<SDTypeConstraint> constraints> :
+        SDTypeProfile<0, 1, constraints>;
+class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
+        SDTypeProfile<0, 2, constraints>;
 
 //===----------------------------------------------------------------------===//
 // Selection DAG Node Properties.
@@ -180,6 +217,10 @@ def SDNPHasChain    : SDNodeProperty;   // R/W chain operand and result
 def SDNPOutFlag     : SDNodeProperty;   // Write a flag result
 def SDNPInFlag      : SDNodeProperty;   // Read a flag operand
 def SDNPOptInFlag   : SDNodeProperty;   // Optionally read a flag operand
+def SDNPMayStore    : SDNodeProperty;   // May write to memory, sets 'mayStore'.
+def SDNPMayLoad     : SDNodeProperty;   // May read memory, sets 'mayLoad'.
+def SDNPSideEffect  : SDNodeProperty;   // Sets 'HasUnmodelledSideEffects'.
+def SDNPMemOperand  : SDNodeProperty;   // Touches memory, has assoc MemOperand
 
 //===----------------------------------------------------------------------===//
 // Selection DAG Node definitions.
@@ -193,12 +234,14 @@ class SDNode<string opcode, SDTypeProfile typeprof,
 }
 
 def set;
+def implicit;
+def parallel;
 def node;
 def srcvalue;
 
 def imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
-def fpimm      : SDNode<"ISD::TargetConstantFP",
-                         SDTFPLeaf, [], "ConstantFPSDNode">;
+def timm   : SDNode<"ISD::TargetConstant", SDTIntLeaf , [], "ConstantSDNode">;
+def fpimm      : SDNode<"ISD::ConstantFP", SDTFPLeaf  , [], "ConstantFPSDNode">;
 def vt         : SDNode<"ISD::VALUETYPE" , SDTOther   , [], "VTSDNode">;
 def bb         : SDNode<"ISD::BasicBlock", SDTOther   , [], "BasicBlockSDNode">;
 def cond       : SDNode<"ISD::CONDCODE"  , SDTOther   , [], "CondCodeSDNode">;
@@ -207,6 +250,10 @@ def globaladdr : SDNode<"ISD::GlobalAddress",         SDTPtrLeaf, [],
                         "GlobalAddressSDNode">;
 def tglobaladdr : SDNode<"ISD::TargetGlobalAddress",  SDTPtrLeaf, [],
                          "GlobalAddressSDNode">;
+def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress",         SDTPtrLeaf, [],
+                          "GlobalAddressSDNode">;
+def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress",  SDTPtrLeaf, [],
+                           "GlobalAddressSDNode">;
 def constpool   : SDNode<"ISD::ConstantPool",         SDTPtrLeaf, [],
                          "ConstantPoolSDNode">;
 def tconstpool  : SDNode<"ISD::TargetConstantPool",   SDTPtrLeaf, [],
@@ -265,6 +312,9 @@ def zext       : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
 def anyext     : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
 def trunc      : SDNode<"ISD::TRUNCATE"   , SDTIntTruncOp>;
 def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>;
+def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
+def insertelt  : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
+
                         
 def fadd       : SDNode<"ISD::FADD"       , SDTFPBinOp, [SDNPCommutative]>;
 def fsub       : SDNode<"ISD::FSUB"       , SDTFPBinOp>;
@@ -276,6 +326,11 @@ def fneg       : SDNode<"ISD::FNEG"       , SDTFPUnaryOp>;
 def fsqrt      : SDNode<"ISD::FSQRT"      , SDTFPUnaryOp>;
 def fsin       : SDNode<"ISD::FSIN"       , SDTFPUnaryOp>;
 def fcos       : SDNode<"ISD::FCOS"       , SDTFPUnaryOp>;
+def frint      : SDNode<"ISD::FRINT"      , SDTFPUnaryOp>;
+def ftrunc     : SDNode<"ISD::FTRUNC"     , SDTFPUnaryOp>;
+def fceil      : SDNode<"ISD::FCEIL"      , SDTFPUnaryOp>;
+def ffloor     : SDNode<"ISD::FFLOOR"     , SDTFPUnaryOp>;
+def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
 
 def fround     : SDNode<"ISD::FP_ROUND"   , SDTFPRoundOp>;
 def fextend    : SDNode<"ISD::FP_EXTEND"  , SDTFPExtendOp>;
@@ -289,25 +344,140 @@ def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
 def setcc      : SDNode<"ISD::SETCC"      , SDTSetCC>;
 def select     : SDNode<"ISD::SELECT"     , SDTSelect>;
 def selectcc   : SDNode<"ISD::SELECT_CC"  , SDTSelectCC>;
+def vsetcc     : SDNode<"ISD::VSETCC"     , SDTSetCC>;
 
 def brcond     : SDNode<"ISD::BRCOND"     , SDTBrcond, [SDNPHasChain]>;
 def brind      : SDNode<"ISD::BRIND"      , SDTBrind,  [SDNPHasChain]>;
 def br         : SDNode<"ISD::BR"         , SDTBr,     [SDNPHasChain]>;
-def ret        : SDNode<"ISD::RET"        , SDTRet,    [SDNPHasChain]>;
+def ret        : SDNode<"ISD::RET"        , SDTNone,   [SDNPHasChain]>;
+def trap       : SDNode<"ISD::TRAP"       , SDTNone,
+                        [SDNPHasChain, SDNPSideEffect]>;
+
+def prefetch   : SDNode<"ISD::PREFETCH"   , STDPrefetch,
+                        [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
+
+def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier,
+                        [SDNPHasChain, SDNPSideEffect]>;
+
+def atomic_cmp_swap_8 : SDNode<"ISD::ATOMIC_CMP_SWAP_8" , STDAtomic3,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_8 : SDNode<"ISD::ATOMIC_LOAD_ADD_8" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_8     : SDNode<"ISD::ATOMIC_SWAP_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_8 : SDNode<"ISD::ATOMIC_LOAD_SUB_8" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_8 : SDNode<"ISD::ATOMIC_LOAD_AND_8" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_8  : SDNode<"ISD::ATOMIC_LOAD_OR_8" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_8 : SDNode<"ISD::ATOMIC_LOAD_XOR_8" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_8: SDNode<"ISD::ATOMIC_LOAD_NAND_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_8 : SDNode<"ISD::ATOMIC_LOAD_MIN_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_8 : SDNode<"ISD::ATOMIC_LOAD_MAX_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_8 : SDNode<"ISD::ATOMIC_LOAD_UMIN_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_8 : SDNode<"ISD::ATOMIC_LOAD_UMAX_8", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_16 : SDNode<"ISD::ATOMIC_CMP_SWAP_16" , STDAtomic3,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_16 : SDNode<"ISD::ATOMIC_LOAD_ADD_16" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_16     : SDNode<"ISD::ATOMIC_SWAP_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_16 : SDNode<"ISD::ATOMIC_LOAD_SUB_16" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_16 : SDNode<"ISD::ATOMIC_LOAD_AND_16" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_16  : SDNode<"ISD::ATOMIC_LOAD_OR_16" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_16 : SDNode<"ISD::ATOMIC_LOAD_XOR_16" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_16: SDNode<"ISD::ATOMIC_LOAD_NAND_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_16 : SDNode<"ISD::ATOMIC_LOAD_MIN_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_16 : SDNode<"ISD::ATOMIC_LOAD_MAX_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_16 : SDNode<"ISD::ATOMIC_LOAD_UMIN_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_16 : SDNode<"ISD::ATOMIC_LOAD_UMAX_16", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_32 : SDNode<"ISD::ATOMIC_CMP_SWAP_32" , STDAtomic3,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_32 : SDNode<"ISD::ATOMIC_LOAD_ADD_32" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_32     : SDNode<"ISD::ATOMIC_SWAP_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_32 : SDNode<"ISD::ATOMIC_LOAD_SUB_32" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_32 : SDNode<"ISD::ATOMIC_LOAD_AND_32" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_32  : SDNode<"ISD::ATOMIC_LOAD_OR_32" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_32 : SDNode<"ISD::ATOMIC_LOAD_XOR_32" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_32: SDNode<"ISD::ATOMIC_LOAD_NAND_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_32 : SDNode<"ISD::ATOMIC_LOAD_MIN_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_32 : SDNode<"ISD::ATOMIC_LOAD_MAX_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_32 : SDNode<"ISD::ATOMIC_LOAD_UMIN_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_32 : SDNode<"ISD::ATOMIC_LOAD_UMAX_32", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_64 : SDNode<"ISD::ATOMIC_CMP_SWAP_64" , STDAtomic3,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_64 : SDNode<"ISD::ATOMIC_LOAD_ADD_64" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_64     : SDNode<"ISD::ATOMIC_SWAP_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_64 : SDNode<"ISD::ATOMIC_LOAD_SUB_64" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_64 : SDNode<"ISD::ATOMIC_LOAD_AND_64" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_64  : SDNode<"ISD::ATOMIC_LOAD_OR_64" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_64 : SDNode<"ISD::ATOMIC_LOAD_XOR_64" , STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_64: SDNode<"ISD::ATOMIC_LOAD_NAND_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_64 : SDNode<"ISD::ATOMIC_LOAD_MIN_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_64 : SDNode<"ISD::ATOMIC_LOAD_MAX_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_64 : SDNode<"ISD::ATOMIC_LOAD_UMIN_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_64 : SDNode<"ISD::ATOMIC_LOAD_UMAX_64", STDAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
 
 // Do not use ld, st directly. Use load, extload, sextload, zextload, store,
 // and truncst (see below).
-def ld         : SDNode<"ISD::LOAD"       , SDTLoad,  [SDNPHasChain]>;
-def st         : SDNode<"ISD::STORE"      , SDTStore, [SDNPHasChain]>;
+def ld         : SDNode<"ISD::LOAD"       , SDTLoad,
+                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def st         : SDNode<"ISD::STORE"      , SDTStore,
+                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def ist        : SDNode<"ISD::STORE"      , SDTIStore,
+                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
 
 def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
-def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, 0, []>, []>;
+def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
 def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
                               []>;
 def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
     SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
 def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
     SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
+    
+def extract_subreg : SDNode<"ISD::EXTRACT_SUBREG", 
+    SDTypeProfile<1, 2, []>>;
+def insert_subreg : SDNode<"ISD::INSERT_SUBREG", 
+    SDTypeProfile<1, 3, []>>;
 
 // Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
 // these internally.  Don't reference these directly.
@@ -377,136 +547,203 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
 
 // Leaf fragments.
 
-def vtInt      : PatLeaf<(vt),  [{ return MVT::isInteger(N->getVT()); }]>;
-def vtFP       : PatLeaf<(vt),  [{ return MVT::isFloatingPoint(N->getVT()); }]>;
+def vtInt      : PatLeaf<(vt),  [{ return N->getVT().isInteger(); }]>;
+def vtFP       : PatLeaf<(vt),  [{ return N->getVT().isFloatingPoint(); }]>;
 
 def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
 def immAllOnesV: PatLeaf<(build_vector), [{
   return ISD::isBuildVectorAllOnes(N);
 }]>;
+def immAllOnesV_bc: PatLeaf<(bitconvert), [{
+  return ISD::isBuildVectorAllOnes(N);
+}]>;
 def immAllZerosV: PatLeaf<(build_vector), [{
   return ISD::isBuildVectorAllZeros(N);
 }]>;
-
-def immAllOnesV_bc: PatLeaf<(bitconvert), [{
-  return ISD::isBuildVectorAllOnes(N);
+def immAllZerosV_bc: PatLeaf<(bitconvert), [{
+  return ISD::isBuildVectorAllZeros(N);
 }]>;
 
 
+
 // Other helper fragments.
 def not  : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>;
 def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
 def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>;
 def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
 
-def load : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  return ISD::isNON_EXTLoad(N);
+// load fragments.
+def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
+  return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
 }]>;
 
 // extending load fragments.
-def extloadi1  : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i1;
-  return false;
-}]>;
-def extloadi8  : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i8;
-  return false;
-}]>;
-def extloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i16;
-  return false;
-}]>;
-def extloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i32;
-  return false;
-}]>;
-def extloadf32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::f32;
-  return false;
-}]>;
-
-def sextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isSEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i1;
-  return false;
-}]>;
-def sextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isSEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i8;
-  return false;
-}]>;
-def sextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isSEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i16;
-  return false;
-}]>;
-def sextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isSEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i32;
-  return false;
-}]>;
-
-def zextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isZEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i1;
-  return false;
-}]>;
-def zextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isZEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i8;
-  return false;
-}]>;
-def zextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isZEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i16;
-  return false;
-}]>;
-def zextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
-  if (ISD::isZEXTLoad(N))
-    return cast<LoadSDNode>(N)->getLoadedVT() == MVT::i32;
-  return false;
+def extload   : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+}]>;
+def sextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+}]>;
+def zextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+}]>;
+
+def extloadi1  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def extloadi8  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f64;
 }]>;
 
+def sextloadi1  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def sextloadi8  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def zextloadi1  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def zextloadi8  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+// store fragments.
+def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
+                             (st node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
 def store : PatFrag<(ops node:$val, node:$ptr),
-                    (st node:$val, node:$ptr), [{
-  return ISD::isNON_TRUNCStore(N);
+                    (unindexedstore node:$val, node:$ptr), [{
+  return !cast<StoreSDNode>(N)->isTruncatingStore();
 }]>;
 
 // truncstore fragments.
-def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
-                           (st node:$val, node:$ptr), [{
-  if (ISD::isTRUNCStore(N))
-    return cast<StoreSDNode>(N)->getStoredVT() == MVT::i1;
-  return false;
+def truncstore : PatFrag<(ops node:$val, node:$ptr),
+                         (unindexedstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->isTruncatingStore();
 }]>;
 def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
-                           (st node:$val, node:$ptr), [{
-  if (ISD::isTRUNCStore(N))
-    return cast<StoreSDNode>(N)->getStoredVT() == MVT::i8;
-  return false;
+                           (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
 }]>;
 def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
-                            (st node:$val, node:$ptr), [{
-  if (ISD::isTRUNCStore(N))
-    return cast<StoreSDNode>(N)->getStoredVT() == MVT::i16;
-  return false;
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
 }]>;
 def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
-                            (st node:$val, node:$ptr), [{
-  if (ISD::isTRUNCStore(N))
-    return cast<StoreSDNode>(N)->getStoredVT() == MVT::i32;
-  return false;
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
 }]>;
 def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
-                            (st node:$val, node:$ptr), [{
-  if (ISD::isTRUNCStore(N))
-    return cast<StoreSDNode>(N)->getStoredVT() == MVT::f32;
-  return false;
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+// indexed store fragments.
+def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
+                     (ist node:$val, node:$base, node:$offset), [{
+  return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
+def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
+                        (istore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+
+def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
+                          (ist node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+                          (itruncstore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                            (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                            (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+
+def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
+                         (istore node:$val, node:$ptr, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+
+def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+                           (itruncstore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
 }]>;
 
 // setcc convenience fragments.
@@ -576,6 +813,12 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
 //===----------------------------------------------------------------------===//
 // Complex pattern definitions.
 //
+
+class CPAttribute;
+// Pass the parent Operand as root to CP function rather 
+// than the root of the sub-DAG
+def CPAttrParentAsRoot : CPAttribute;
+
 // Complex patterns, e.g. X86 addressing mode, requires pattern matching code
 // in C++. NumOperands is the number of operands returned by the select function;
 // SelectFunc is the name of the function used to pattern match the max. pattern;
@@ -583,12 +826,14 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
 // e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
 //
 class ComplexPattern<ValueType ty, int numops, string fn,
-                     list<SDNode> roots = [], list<SDNodeProperty> props = []> {
+                     list<SDNode> roots = [], list<SDNodeProperty> props = [],
+                     list<CPAttribute> attrs = []> {
   ValueType Ty = ty;
   int NumOperands = numops;
   string SelectFunc = fn;
   list<SDNode> RootNodes = roots;
   list<SDNodeProperty> Properties = props;
+  list<CPAttribute> Attributes = attrs;
 }
 
 //===----------------------------------------------------------------------===//
@@ -597,9 +842,3 @@ class ComplexPattern<ValueType ty, int numops, string fn,
 def SDT_dwarf_loc : SDTypeProfile<0, 3,
                       [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
 def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
-
-def SDT_dwarf_label : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
-def dwarf_label : SDNode<"ISD::DEBUG_LABEL", SDT_dwarf_label,[SDNPHasChain]>;
-
-
-