It’s time for another round of “What is the canonical IR?”
Credit for this episode to Zvi and PR31551.
https://llvm.org/bugs/show_bug.cgi?id=31551
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
}
Potential reasons to prefer one or the other:
-
Shuffle is the most compact.
-
Trunc is easier to read.
-
One of these is easier for value tracking.
-
Compatibility with existing IR transforms (eg, InterleavedAccess recognizes the shuffle form).
-
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?).