<div dir="ltr"><div>My grasp of LLVM history isn't great, but I think these are missing because there wasn't much need for vector optimization in IR because there just weren't that many vector opportunities in IR. Ie, the vectorizers are relatively new, and hand-written vector code (eg, SSE intrinsics in source) generally went straight to the backend as target-specific IR intrinsics. <br><br>Now that we're vectorizing more aggressively (and plan to do even more) and we're converting target-specific vector source to generic vector IR whenever possible, it makes sense to add these kinds of optimizations.<br><br></div>One frequently visible sign of scalar privilege in instcombine is the use of "m_ConstantInt". In many cases, this can be converted to "m_APInt" without much effort, and the transform will auto-magically apply to splat vector constants too.<br><div><br><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 29, 2017 at 8:37 PM, Rackover, Zvi <span dir="ltr"><<a href="mailto:zvi.rackover@intel.com" target="_blank">zvi.rackover@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div link="#0563C1" vlink="#954F72" lang="EN-US">
<div class="m_-6279592968582731852WordSection1">
<p class="MsoNormal">As Sanjay noted in <a href="https://reviews.llvm.org/D31426#712701" target="_blank">
D31426</a>, InstructionSimplify is missing the following simplification:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">This function:<u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @splat_operand(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %splat = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> %splat, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 1><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">can be simplified to:<u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @splat_operand(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  %shuf = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">InstCombine covers this case inefficiently.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I noticed that InstructionSimplify does not do any simplifications for shufflevector’s other than constant folding. I just wanted to be sure there is no compelling reason for this before I start streaming patches. I assume that this is
 not related to our conservative approach of refraining from creation of new shuffle masks that may hurt some target.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Here are some more opportunities that can be added to InstructionSimplify, all of which are covered by InstCombine:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @undef_mask(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> undef<u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span><u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @undef_mask(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> undef<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @identity_mask_0(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span><u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @identity_mask_0(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> %x<u></u><u></u></p>
<p class="MsoNormal">} <u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @identity_mask_1(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> undef, <4 x i32> %x, <4 x i32> <i32 4, i32 5, i32 6, i32 7><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span><u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @identity_mask_1(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> %x<u></u><u></u></p>
<p class="MsoNormal">} <u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @pseudo_identity_mask(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 2, i32 7><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span> <u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @pseudo_identity_mask(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> %x<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @const_operand(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %shuf = shufflevector <4 x i32> <i32 42, i32 43, i32 44, i32 45>, <4 x i32> %x, <4 x i32> <i32 0, i32 3, i32 2, i32 1><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %shuf<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span><u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @const_operand(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> <i32 42, i32 45, i32 44, i32 43><u></u><u></u></p>
<p class="MsoNormal">} <u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">define <4 x i32> @merge(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">   %lower = shufflevector <4 x i32> %x, <4 x i32> undef, <2 x i32> <i32 1, i32 0><u></u><u></u></p>
<p class="MsoNormal">   %upper = shufflevector <4 x i32> %x, <4 x i32> undef, <2 x i32> <i32 2, i32 3><u></u><u></u></p>
<p class="MsoNormal">   %merged = shufflevector <2 x i32> %upper, <2 x i32> %lower, <4 x i32> <i32 3, i32 2, i32 0, i32 1><u></u><u></u></p>
<p class="MsoNormal">   ret <4 x i32> %merged<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:Wingdings">à</span><u></u><u></u></p>
<p class="MsoNormal">define <4 x i32> @merge(<4 x i32> %x) {<u></u><u></u></p>
<p class="MsoNormal">  ret <4 x i32> %x<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Would appreciate your comments and feedback.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks, Zvi<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p>------------------------------<wbr>------------------------------<wbr>---------<br>
Intel Israel (74) Limited</p>

<p>This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</p></div>

</blockquote></div><br></div>