<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=""><div class="">Hi Elena, </div><div class=""><br class=""></div><div class="">I think that in general this proposal makes sense and is consistent with discussions that we’ve had in the past. These new intrinsics can be very useful for vectorization.  I have a few comments below</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 18, 2014, at 6:40 AM, Demikhovsky, Elena <<a href="mailto:elena.demikhovsky@intel.com" class="">elena.demikhovsky@intel.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><font face="Calibri" size="2" style="font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-size: 11pt;" class=""><div class="">Hi,</div><div class=""> </div><div class="">Recent Intel architectures AVX-512 and AVX2 provide vector gather and/or scatter instructions.</div><div class="">Gather/scatter instructions allow read/write access to multiple memory addresses. The addresses are specified using a base address and a vector of indices.</div><div class="">We’d like Vectorizers to tap this functionality, and propose to do so by introducing new intrinsics:</div><div class=""> </div><div class="">VectorValue = @llvm.sindex.load (BaseAddr, VectorOfIndices, Scale)</div><div class="">VectorValue = @llvm.uindex.load (BaseAddr, VectorOfIndices, Scale)</div><div class="">VectorValue = @llvm.sindex.masked.load (BaseAddr, VectorOfIndices, Scale, PassThruVal, Mask)</div><div class="">VectorValue = @llvm.uindex.masked.load (BaseAddr, VectorOfIndices, Scale, PassThruVal, Mask)</div><div class=""> </div></span></font></div></blockquote><div><br class=""></div><div>It looks like the proposed intrinsic is very specific to the x86 implementation of gather/scatter.  Would it be possible to remove the PassThrough value from the intrinsic and define the masked-out value to be undef?  You would still be able to pattern match it if you use a maskedload + select. </div><div><br class=""></div><div>Can we remove the masked version of the intrinsic altogether and pattern match it using the non-masked version somehow?</div><div><br class=""></div><div>Can we infer the scale value based on the loaded element type?</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><font face="Calibri" size="2" style="font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-size: 11pt;" class=""><div class="">Semantics:</div><div class="">For i=0,1,…,N-1: if (Mask[i]) {VectorValue[i] = *(BaseAddr + VectorOfIndices[i]*Scale) else VectorValue[i]=PassThruVal[i];}</div><div class=""> </div><div class="">void @llvm.sindex.store (BaseAddr, VectorValue, VectorOfIndices, Scale)</div><div class="">void @llvm.uindex.store (BaseAddr, VectorValue, VectorOfIndices, Scale)</div><div class="">void @llvm.sindex.masked.store (BaseAddr, VectorValue, VectorOfIndices, Scale, Mask)</div><div class="">void @llvm.uindex.masked.store (BaseAddr, VectorValue, VectorOfIndices, Scale, Mask)</div><div class=""> </div><div class="">Semantics:</div><div class="">For i=0,1,…,N-1: if (Mask[i]) {*(BaseAddr + VectorOfIndices[i]*Scale) = VectorValue[i];}</div><div class=""> </div><div class="">VectorValue: any float or integer vector type.</div></span></font></div></blockquote><div><br class=""></div><div>We should also support loading and storing pointer values. </div><br class=""><blockquote type="cite" class=""><div class=""><font face="Calibri" size="2" style="font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-size: 11pt;" class=""><div class="">BaseAddr: a pointer; may be zero if full address is placed in the index.</div><div class="">VectorOfIndices: a vector of i32 or i64 signed or unsigned integer values.</div><div class="">Scale: a compile time constant 1, 2, 4 or 8.</div></span></font></div></blockquote><div><br class=""></div><div>Why do we need to limit the scale values?</div><br class=""><blockquote type="cite" class=""><div class=""><font face="Calibri" size="2" style="font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-size: 11pt;" class=""><div class="">VectorValue, VectorOfIndices and Mask must have the same vector width.</div><div class=""> </div><div class="">An indexed store instruction with complete or partial overlap in memory (i.e., two indices with same or close values) will provide the result equivalent to serial scalar stores from least to most significant vector elements.</div><div class=""> </div></span></font></div></blockquote><br class=""></div><div>Thanks,</div><div>Nadav</div><br class=""></body></html>