<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Elena,<div class=""><br class=""></div><div class="">Was this OKed by Craig or someone?  <a href="http://reviews.llvm.org/D7665" class="">http://reviews.llvm.org/D7665</a> has no comments.</div><div class=""><br class=""></div><div class="">Sorry I didn’t feel qualified to review this but my feeling is that the tablegen part should probably be a separate a patch.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Adam</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 25, 2015, at 1:46 AM, Elena Demikhovsky <<a href="mailto:elena.demikhovsky@intel.com" class="">elena.demikhovsky@intel.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">Author: delena<br class="">Date: Wed Feb 25 03:46:31 2015<br class="">New Revision: 230471<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=230471&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=230471&view=rev</a><br class="">Log:<br class="">AVX-512: Gather and Scatter patterns<br class="">Gather and scatter instructions additionally write to one of the source operands - mask register.<br class="">In this case Gather has 2 destination values - the loaded value and the mask.<br class="">Till now we did not support code gen pattern for gather - the instruction was generated from <br class="">intrinsic only and machine node was hardcoded.<br class="">When we introduce the masked_gather node, we need to select instruction automatically,<br class="">in the standard way.<br class="">I added a flag "hasTwoExplicitDefs" that allows to handle 2 destination operands.<br class=""><br class="">(Some code in the X86InstrFragmentsSIMD.td is commented out, just to split one big<br class="">patch in many small patches)<br class=""><br class=""><br class="">Modified:<br class="">    llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h<br class="">    llvm/trunk/include/llvm/Target/Target.td<br class="">    llvm/trunk/include/llvm/Target/TargetSelectionDAG.td<br class="">    llvm/trunk/lib/Target/X86/X86InstrAVX512.td<br class="">    llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td<br class="">    llvm/trunk/lib/Target/X86/X86InstrInfo.td<br class="">    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp<br class="">    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp<br class="">    llvm/trunk/utils/TableGen/CodeGenInstruction.h<br class=""><br class="">Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)<br class="">+++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Wed Feb 25 03:46:31 2015<br class="">@@ -689,6 +689,8 @@ namespace ISD {<br class=""><br class="">     // Masked load and store<br class="">     MLOAD, MSTORE,<br class="">+    // Masked gather and scatter<br class="">+    MGATHER, MSCATTER,<br class=""><br class="">     /// This corresponds to the llvm.lifetime.* intrinsics. The first operand<br class="">     /// is the chain and the second operand is the alloca pointer.<br class=""><br class="">Modified: llvm/trunk/include/llvm/Target/Target.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/Target/Target.td (original)<br class="">+++ llvm/trunk/include/llvm/Target/Target.td Wed Feb 25 03:46:31 2015<br class="">@@ -397,7 +397,8 @@ class Instruction {<br class="">   //    captured by any operands of the instruction or other flags.<br class="">   //<br class="">   bit hasSideEffects = ?;<br class="">-<br class="">+  bit hasTwoExplicitDefs = 0;  // Does this instruction have 2 explicit<br class="">+                               // destinations?<br class="">   // Is this instruction a "real" instruction (with a distinct machine<br class="">   // encoding), or is it a pseudo instruction used for codegen modeling<br class="">   // purposes.<br class=""><br class="">Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)<br class="">+++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Wed Feb 25 03:46:31 2015<br class="">@@ -196,6 +196,14 @@ def SDTMaskedLoad: SDTypeProfile<1, 3, [<br class="">   SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisVec<2>, SDTCisSameAs<0, 3><br class=""> ]>;<br class=""><br class="">+def SDTMaskedGather: SDTypeProfile<1, 3, [       // masked gather<br class="">+  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2><br class="">+]>;<br class="">+<br class="">+def SDTMaskedScatter: SDTypeProfile<1, 3, [       // masked scatter<br class="">+  SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2><br class="">+]>;<br class="">+<br class=""> def SDTVecShuffle : SDTypeProfile<1, 2, [<br class="">   SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2><br class=""> ]>;<br class="">@@ -468,6 +476,10 @@ def masked_store : SDNode<"ISD::MSTORE",<br class="">                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;<br class=""> def masked_load  : SDNode<"ISD::MLOAD",  SDTMaskedLoad,<br class="">                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;<br class="">+def masked_scatter : SDNode<"ISD::MSCATTER",  SDTMaskedScatter,<br class="">+                       [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;<br class="">+def masked_gather  : SDNode<"ISD::MGATHER",  SDTMaskedGather,<br class="">+                       [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;<br class=""><br class=""> // Do not use ld, st directly. Use load, extload, sextload, zextload, store,<br class=""> // and truncst (see below).<br class=""><br class="">Modified: llvm/trunk/lib/Target/X86/X86InstrAVX512.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrAVX512.td?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrAVX512.td?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/X86/X86InstrAVX512.td (original)<br class="">+++ llvm/trunk/lib/Target/X86/X86InstrAVX512.td Wed Feb 25 03:46:31 2015<br class="">@@ -4919,74 +4919,81 @@ defm VPMOVSXDQZ: avx512_extend<0x25, "vp<br class=""> //===----------------------------------------------------------------------===//<br class=""> // GATHER - SCATTER Operations<br class=""><br class="">-multiclass avx512_gather<bits<8> opc, string OpcodeStr, RegisterClass KRC,<br class="">-                       RegisterClass RC, X86MemOperand memop> {<br class="">-let mayLoad = 1,<br class="">+multiclass avx512_gather<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,<br class="">+                         X86MemOperand memop, PatFrag GatherNode> {<br class="">+let mayLoad = 1, hasTwoExplicitDefs = 1,<br class="">   Constraints = "@earlyclobber $dst, $src1 = $dst, $mask = $mask_wb" in<br class="">-  def rm  : AVX5128I<opc, MRMSrcMem, (outs RC:$dst, KRC:$mask_wb),<br class="">-            (ins RC:$src1, KRC:$mask, memop:$src2),<br class="">+  def rm  : AVX5128I<opc, MRMSrcMem, (outs _.RC:$dst, _.KRCWM:$mask_wb),<br class="">+            (ins _.RC:$src1, _.KRCWM:$mask, memop:$src2),<br class="">             !strconcat(OpcodeStr,<br class="">             "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),<br class="">-            []>, EVEX, EVEX_K;<br class="">+            [(set _.RC:$dst, _.KRCWM:$mask_wb,<br class="">+              (_.VT (GatherNode  (_.VT _.RC:$src1), _.KRCWM:$mask,<br class="">+                     vectoraddr:$src2)))]>, EVEX, EVEX_K,<br class="">+             EVEX_CD8<_.EltSize, CD8VT1>;<br class=""> }<br class=""><br class=""> let ExeDomain = SSEPackedDouble in {<br class="">-defm VGATHERDPDZ : avx512_gather<0x92, "vgatherdpd", VK8WM, VR512, vy64xmem>,<br class="">-                                 EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VGATHERQPDZ : avx512_gather<0x93, "vgatherqpd", VK8WM, VR512, vz64mem>,<br class="">-                                 EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">+defm VGATHERDPDZ : avx512_gather<0x92, "vgatherdpd", v8f64_info, vy64xmem,<br class="">+                                 mgatherv8i32>, EVEX_V512, VEX_W;<br class="">+defm VGATHERQPDZ : avx512_gather<0x93, "vgatherqpd", v8f64_info, vz64mem,<br class="">+                                 mgatherv8i64>, EVEX_V512, VEX_W;<br class=""> }<br class=""><br class=""> let ExeDomain = SSEPackedSingle in {<br class="">-defm VGATHERDPSZ : avx512_gather<0x92, "vgatherdps", VK16WM, VR512, vz32mem>,<br class="">-                                 EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">-defm VGATHERQPSZ : avx512_gather<0x93, "vgatherqps", VK8WM, VR256X, vz64mem>,<br class="">-                                 EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">-}<br class="">-<br class="">-defm VPGATHERDQZ : avx512_gather<0x90, "vpgatherdq", VK8WM, VR512,  vy64xmem>,<br class="">-                                 EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VPGATHERDDZ : avx512_gather<0x90, "vpgatherdd", VK16WM, VR512, vz32mem>,<br class="">-                                 EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">-<br class="">-defm VPGATHERQQZ : avx512_gather<0x91, "vpgatherqq", VK8WM, VR512,  vz64mem>,<br class="">-                                 EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VPGATHERQDZ : avx512_gather<0x91, "vpgatherqd", VK8WM, VR256X,  vz64mem>,<br class="">-                                 EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">+defm VGATHERDPSZ : avx512_gather<0x92, "vgatherdps", v16f32_info, vz32mem,<br class="">+                                 mgatherv16i32>, EVEX_V512;<br class="">+defm VGATHERQPSZ : avx512_gather<0x93, "vgatherqps", v8f32x_info, vz64mem,<br class="">+                                 mgatherv8i64>,  EVEX_V512;<br class="">+}<br class="">+<br class="">+defm VPGATHERDQZ : avx512_gather<0x90, "vpgatherdq", v8i64_info,  vy64xmem,<br class="">+                                 mgatherv8i32>, EVEX_V512, VEX_W;<br class="">+defm VPGATHERDDZ : avx512_gather<0x90, "vpgatherdd", v16i32_info, vz32mem,<br class="">+                                 mgatherv16i32>, EVEX_V512;<br class="">+<br class="">+defm VPGATHERQQZ : avx512_gather<0x91, "vpgatherqq", v8i64_info,  vz64mem,<br class="">+                                 mgatherv8i64>, EVEX_V512, VEX_W;<br class="">+defm VPGATHERQDZ : avx512_gather<0x91, "vpgatherqd", v8i32x_info,  vz64mem,<br class="">+                                 mgatherv8i64>, EVEX_V512;<br class="">+<br class="">+multiclass avx512_scatter<bits<8> opc, string OpcodeStr, X86VectorVTInfo _,<br class="">+                          X86MemOperand memop, PatFrag ScatterNode> {<br class=""><br class="">-multiclass avx512_scatter<bits<8> opc, string OpcodeStr, RegisterClass KRC,<br class="">-                       RegisterClass RC, X86MemOperand memop> {<br class=""> let mayStore = 1, Constraints = "$mask = $mask_wb" in<br class="">-  def mr  : AVX5128I<opc, MRMDestMem, (outs KRC:$mask_wb),<br class="">-            (ins memop:$dst, KRC:$mask, RC:$src2),<br class="">+<br class="">+  def mr  : AVX5128I<opc, MRMDestMem, (outs _.KRCWM:$mask_wb),<br class="">+            (ins memop:$dst, _.KRCWM:$mask, _.RC:$src),<br class="">             !strconcat(OpcodeStr,<br class="">-            "\t{$src2, ${dst} {${mask}}|${dst} {${mask}}, $src2}"),<br class="">-            []>, EVEX, EVEX_K;<br class="">+            "\t{$src, ${dst} {${mask}}|${dst} {${mask}}, $src}"),<br class="">+            [(set _.KRCWM:$mask_wb, (ScatterNode (_.VT _.RC:$src),<br class="">+                                     _.KRCWM:$mask,  vectoraddr:$dst))]>,<br class="">+            EVEX, EVEX_K, EVEX_CD8<_.EltSize, CD8VT1>;<br class=""> }<br class=""><br class=""> let ExeDomain = SSEPackedDouble in {<br class="">-defm VSCATTERDPDZ : avx512_scatter<0xA2, "vscatterdpd", VK8WM, VR512, vy64xmem>,<br class="">-                                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VSCATTERQPDZ : avx512_scatter<0xA3, "vscatterqpd", VK8WM, VR512, vz64mem>,<br class="">-                                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">+defm VSCATTERDPDZ : avx512_scatter<0xA2, "vscatterdpd", v8f64_info, vy64xmem,<br class="">+                                   mscatterv8i32>, EVEX_V512, VEX_W;<br class="">+defm VSCATTERQPDZ : avx512_scatter<0xA3, "vscatterqpd", v8f64_info, vz64mem,<br class="">+                                   mscatterv8i64>, EVEX_V512, VEX_W;<br class=""> }<br class=""><br class=""> let ExeDomain = SSEPackedSingle in {<br class="">-defm VSCATTERDPSZ : avx512_scatter<0xA2, "vscatterdps", VK16WM, VR512, vz32mem>,<br class="">-                                   EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">-defm VSCATTERQPSZ : avx512_scatter<0xA3, "vscatterqps", VK8WM, VR256X, vz64mem>,<br class="">-                                   EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">+defm VSCATTERDPSZ : avx512_scatter<0xA2, "vscatterdps", v16f32_info, vz32mem,<br class="">+                                   mscatterv16i32>, EVEX_V512;<br class="">+defm VSCATTERQPSZ : avx512_scatter<0xA3, "vscatterqps", v8f32x_info, vz64mem,<br class="">+                                   mscatterv8i64>, EVEX_V512;<br class=""> }<br class=""><br class="">-defm VPSCATTERDQZ : avx512_scatter<0xA0, "vpscatterdq", VK8WM, VR512, vy64xmem>,<br class="">-                                   EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VPSCATTERDDZ : avx512_scatter<0xA0, "vpscatterdd", VK16WM, VR512, vz32mem>,<br class="">-                                   EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">-<br class="">-defm VPSCATTERQQZ : avx512_scatter<0xA1, "vpscatterqq", VK8WM, VR512, vz64mem>,<br class="">-                                  EVEX_V512, VEX_W, EVEX_CD8<64, CD8VT1>;<br class="">-defm VPSCATTERQDZ : avx512_scatter<0xA1, "vpscatterqd", VK8WM, VR256X, vz64mem>,<br class="">-                                  EVEX_V512, EVEX_CD8<32, CD8VT1>;<br class="">+defm VPSCATTERDQZ : avx512_scatter<0xA0, "vpscatterdq", v8i64_info, vy64xmem,<br class="">+                                   mscatterv8i32>, EVEX_V512, VEX_W;<br class="">+defm VPSCATTERDDZ : avx512_scatter<0xA0, "vpscatterdd", v16i32_info, vz32mem,<br class="">+                                   mscatterv16i32>, EVEX_V512;<br class="">+<br class="">+defm VPSCATTERQQZ : avx512_scatter<0xA1, "vpscatterqq", v8i64_info, vz64mem,<br class="">+                                   mscatterv8i64>, EVEX_V512, VEX_W;<br class="">+defm VPSCATTERQDZ : avx512_scatter<0xA1, "vpscatterqd", v8i32x_info, vz64mem,<br class="">+                                   mscatterv8i64>, EVEX_V512;<br class=""><br class=""> // prefetch<br class=""> multiclass avx512_gather_scatter_prefetch<bits<8> opc, Format F, string OpcodeStr,<br class=""><br class="">Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original)<br class="">+++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Wed Feb 25 03:46:31 2015<br class="">@@ -304,6 +304,8 @@ def X86exp2      : SDNode<"X86ISD::EXP2"<br class=""> def X86rsqrt28s  : SDNode<"X86ISD::RSQRT28",  STDFp2SrcRm>;<br class=""> def X86rcp28s    : SDNode<"X86ISD::RCP28",    STDFp2SrcRm>;<br class=""> def X86RndScale  : SDNode<"X86ISD::RNDSCALE", STDFp3SrcRm>;<br class="">+def X86mgather   : SDNode<"X86ISD::GATHER", SDTypeProfile<1, 3, <br class="">+                          [SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>]>>;<br class=""><br class=""> def SDT_PCMPISTRI : SDTypeProfile<2, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,<br class="">                                          SDTCisVT<2, v16i8>, SDTCisVT<3, v16i8>,<br class="">@@ -524,6 +526,58 @@ def unalignednontemporalstore : PatFrag<<br class="">   return false;<br class=""> }]>;<br class=""><br class="">+def mgatherv8i32 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_gather node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedGatherSDNode *Mgt = dyn_cast<MaskedGatherSDNode>(N))<br class="">+  //  return (Mgt->getIndex().getValueType() == MVT::v8i32 ||<br class="">+  //          Mgt->getBasePtr().getValueType() == MVT::v8i32);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+<br class="">+def mgatherv8i64 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_gather node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedGatherSDNode *Mgt = dyn_cast<MaskedGatherSDNode>(N))<br class="">+  //  return (Mgt->getIndex().getValueType() == MVT::v8i64 ||<br class="">+  //          Mgt->getBasePtr().getValueType() == MVT::v8i64);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+def mgatherv16i32 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_gather node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedGatherSDNode *Mgt = dyn_cast<MaskedGatherSDNode>(N))<br class="">+  //  return (Mgt->getIndex().getValueType() == MVT::v16i32 ||<br class="">+  //          Mgt->getBasePtr().getValueType() == MVT::v16i32);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+<br class="">+def mscatterv8i32 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_scatter node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedScatterSDNode *Sc = dyn_cast<MaskedScatterSDNode>(N))<br class="">+  //  return (Sc->getIndex().getValueType() == MVT::v8i32 ||<br class="">+  //          Sc->getBasePtr().getValueType() == MVT::v8i32);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+<br class="">+def mscatterv8i64 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_scatter node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedScatterSDNode *Sc = dyn_cast<MaskedScatterSDNode>(N))<br class="">+  //  return (Sc->getIndex().getValueType() == MVT::v8i64 ||<br class="">+  //          Sc->getBasePtr().getValueType() == MVT::v8i64);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+def mscatterv16i32 : PatFrag<(ops node:$src1, node:$src2, node:$src3),<br class="">+  (masked_scatter node:$src1, node:$src2, node:$src3) , [{<br class="">+  //if (MaskedScatterSDNode *Sc = dyn_cast<MaskedScatterSDNode>(N))<br class="">+  //  return (Sc->getIndex().getValueType() == MVT::v16i32 ||<br class="">+  //          Sc->getBasePtr().getValueType() == MVT::v16i32);<br class="">+  //return false;<br class="">+  return N != 0;<br class="">+}]>;<br class="">+<br class=""> // 128-bit bitconvert pattern fragments<br class=""> def bc_v4f32 : PatFrag<(ops node:$in), (v4f32 (bitconvert node:$in))>;<br class=""> def bc_v2f64 : PatFrag<(ops node:$in), (v2f64 (bitconvert node:$in))>;<br class=""><br class="">Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br class="">+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed Feb 25 03:46:31 2015<br class="">@@ -713,6 +713,9 @@ def tls64addr : ComplexPattern<i64, 5, "<br class=""> def tls64baseaddr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",<br class="">                                [tglobaltlsaddr], []>;<br class=""><br class="">+def vectoraddr : ComplexPattern<iPTR, 5, "SelectAddr", [],[SDNPWantParent]>;<br class="">+//def vectoraddr : ComplexPattern<iPTR, 5, "SelectVectorAddr", [],[SDNPWantParent]>;<br class="">+<br class=""> //===----------------------------------------------------------------------===//<br class=""> // X86 Instruction Predicate Definitions.<br class=""> def HasCMov      : Predicate<"Subtarget->hasCMov()">;<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)<br class="">+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Wed Feb 25 03:46:31 2015<br class="">@@ -1113,6 +1113,8 @@ static unsigned GetNumNodeResults(Record<br class=""><br class="">     // FIXME: Should allow access to all the results here.<br class="">     unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;<br class="">+    if (InstInfo.hasTwoExplicitDefs)<br class="">+      ++NumDefsToAdd;<br class=""><br class="">     // Add on one implicit def if it has a resolvable type.<br class="">     if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)<br class="">@@ -1609,11 +1611,20 @@ bool TreePatternNode::ApplyTypeConstrain<br class="">     assert(getNumTypes() == 0 && "Set doesn't produce a value");<br class="">     assert(getNumChildren() >= 2 && "Missing RHS of a set?");<br class="">     unsigned NC = getNumChildren();<br class="">+    unsigned NumOfSrcs = NC-1;<br class=""><br class="">+    // destination<br class="">     TreePatternNode *SetVal = getChild(NC-1);<br class="">     bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters);<br class=""><br class="">-    for (unsigned i = 0; i < NC-1; ++i) {<br class="">+    // second explicit destination<br class="">+    if (TP.getRecord()->getValueAsBit("hasTwoExplicitDefs")) {<br class="">+      TreePatternNode *Set2Val = getChild(NC-2);<br class="">+      MadeChange = Set2Val->ApplyTypeConstraints(TP, NotRegisters);<br class="">+      NumOfSrcs --;<br class="">+    }<br class="">+    <br class="">+    for (unsigned i = 0; i < NumOfSrcs; ++i) {<br class="">       TreePatternNode *Child = getChild(i);<br class="">       MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);<br class=""><br class="">@@ -2856,7 +2867,7 @@ const DAGInstruction &CodeGenDAGPatterns<br class=""><br class="">     // Check that all of the results occur first in the list.<br class="">     std::vector<Record*> Results;<br class="">-    TreePatternNode *Res0Node = nullptr;<br class="">+    SmallVector<TreePatternNode *, 2> ResNode;<br class="">     for (unsigned i = 0; i != NumResults; ++i) {<br class="">       if (i == CGI.Operands.size())<br class="">         I->error("'" + InstResults.begin()->first +<br class="">@@ -2868,8 +2879,7 @@ const DAGInstruction &CodeGenDAGPatterns<br class="">       if (!RNode)<br class="">         I->error("Operand $" + OpName + " does not exist in operand list!");<br class=""><br class="">-      if (i == 0)<br class="">-        Res0Node = RNode;<br class="">+      ResNode.push_back(RNode);<br class="">       Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();<br class="">       if (!R)<br class="">         I->error("Operand $" + OpName + " should be a set destination: all "<br class="">@@ -2946,7 +2956,7 @@ const DAGInstruction &CodeGenDAGPatterns<br class="">                           GetNumNodeResults(I->getRecord(), *this));<br class="">     // Copy fully inferred output node type to instruction result pattern.<br class="">     for (unsigned i = 0; i != NumResults; ++i)<br class="">-      ResultPattern->setType(i, Res0Node->getExtType(i));<br class="">+      ResultPattern->setType(i, ResNode[i]->getExtType(0));<br class=""><br class="">     // Create and insert the instruction.<br class="">     // FIXME: InstImpResults should not be part of DAGInstruction.<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)<br class="">+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Wed Feb 25 03:46:31 2015<br class="">@@ -320,6 +320,7 @@ CodeGenInstruction::CodeGenInstruction(R<br class="">   isRegSequence = R->getValueAsBit("isRegSequence");<br class="">   isExtractSubreg = R->getValueAsBit("isExtractSubreg");<br class="">   isInsertSubreg = R->getValueAsBit("isInsertSubreg");<br class="">+  hasTwoExplicitDefs = R->getValueAsBit("hasTwoExplicitDefs");<br class=""><br class="">   bool Unset;<br class="">   mayLoad      = R->getValueAsBitOrUnset("mayLoad", Unset);<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=230471&r1=230470&r2=230471&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=230471&r1=230470&r2=230471&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original)<br class="">+++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Wed Feb 25 03:46:31 2015<br class="">@@ -255,6 +255,7 @@ namespace llvm {<br class="">     bool isRegSequence : 1;<br class="">     bool isExtractSubreg : 1;<br class="">     bool isInsertSubreg : 1;<br class="">+    bool hasTwoExplicitDefs : 1;<br class=""><br class="">     std::string DeprecatedReason;<br class="">     bool HasComplexDeprecationPredicate;<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits<br class=""></div></blockquote></div><br class=""></div></body></html>