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