<div dir="ltr"><div>It's time for another round of "What is the canonical IR?"<br><br>Credit for this episode to Zvi and PR31551. :)<br><a href="https://llvm.org/bugs/show_bug.cgi?id=31551">https://llvm.org/bugs/show_bug.cgi?id=31551</a><pre class="gmail-bz_comment_text" id="gmail-comment_text_2"><br>define <4 x i16> @shuffle(<16 x i16> %x) {
  %shuf = shufflevector <16 x i16> %x, <16 x i16> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
  ret <4 x i16> %shuf
}

define <4 x i16> @trunc(<16 x i16> %x) {
  %bc = bitcast <16 x i16> %x to <4 x i64>
  %tr = trunc <4 x i64> %bc to <4 x i16>
  ret <4 x i16> %tr
}
<br></pre>Potential reasons to prefer one or the other:<br>1. Shuffle is the most compact.<br>2. Trunc is easier to read.<br>3. One of these is easier for value tracking.<br>4. Compatibility with existing IR transforms (eg, InterleavedAccess recognizes the shuffle form).<br></div>5. We don't create arbitrary shuffle masks in IR because that's bad for a lot of targets (but maybe this mask pattern should always be recognized as special?).<br></div>