llvm.org GIT mirror llvm / 4634fe0
[ARM] Do not convert some vmov instructions Summary: Patch https://reviews.llvm.org/D44467 implements conversion of invalid vmov instructions into valid ones. It turned out that some valid instructions also get converted, for example vmov.i64 d2, #0xff00ff00ff00ff00 -> vmov.i16 d2, #0xff00 Such behavior is incorrect because according to the ARM ARM section F2.7.7 Modified immediate constants in T32 and A32 Advanced SIMD instructions, "On assembly, the data type must be matched in the table if possible." This patch fixes the isNEONmovReplicate check so that the above instruction is not modified any more. Reviewers: rengolin, olista01 Reviewed By: rengolin Subscribers: javed.absar, kristof.beyls, rogfer01, llvm-commits Differential Revision: https://reviews.llvm.org/D44678 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@329158 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Maltsev 2 years ago
2 changed file(s) with 10 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
18671867 ((Value & 0xffffffffff00ffff) == 0xffff);
18681868 }
18691869
1870 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv,
1871 bool AllowMinusOne) const {
1870 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
18721871 assert((Width == 8 || Width == 16 || Width == 32) &&
18731872 "Invalid element width");
18741873 assert(NumElems * Width <= 64 && "Invalid result width");
18871886
18881887 uint64_t Mask = (1ull << Width) - 1;
18891888 uint64_t Elem = Value & Mask;
1890 if (!AllowMinusOne && Elem == Mask)
1891 return false;
18921889 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
18931890 return false;
18941891 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
19031900 }
19041901
19051902 bool isNEONByteReplicate(unsigned NumBytes) const {
1906 return isNEONReplicate(8, NumBytes, false, true);
1903 return isNEONReplicate(8, NumBytes, false);
19071904 }
19081905
19091906 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
19171914 template
19181915 bool isNEONmovReplicate() const {
19191916 checkNeonReplicateArgs(FromW, ToW);
1920 bool AllowMinusOne = ToW != 64;
1921 return isNEONReplicate(FromW, ToW / FromW, false, AllowMinusOne);
1917 if (ToW == 64 && isNEONi64splat())
1918 return false;
1919 return isNEONReplicate(FromW, ToW / FromW, false);
19221920 }
19231921
19241922 template
19251923 bool isNEONinvReplicate() const {
19261924 checkNeonReplicateArgs(FromW, ToW);
1927 return isNEONReplicate(FromW, ToW / FromW, true, true);
1925 return isNEONReplicate(FromW, ToW / FromW, true);
19281926 }
19291927
19301928 bool isNEONi32vmov() const {
2222 @ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
2323 @ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
2424
25 vmov.i64 d2, #0xff00ff00ff00ff00
26 vmov.i64 q2, #0xff00ff00ff00ff00
2527 vmov.i64 d2, #0x00a500a500a500a5
2628 vmov.i64 q2, #0x00a500a500a500a5
2729 vmov.i32 d2, #0x00a500a5
3133 vmov.i32 d2, #0xa500a500
3234 vmov.i32 q2, #0xa500a500
3335
36 @ CHECK: vmov.i64 d2, #0xff00ff00ff00ff00 @ encoding: [0x3a,0x2e,0x82,0xf3]
37 @ CHECK: vmov.i64 q2, #0xff00ff00ff00ff00 @ encoding: [0x7a,0x4e,0x82,0xf3]
3438 @ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]
3539 @ CHECK: vmov.i16 q2, #0xa5 @ encoding: [0x55,0x48,0x82,0xf3]
3640 @ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]