Fix vector packing pseudo-instruction.
When the first source register is different from the destination
register, but equal to the second source, we need to first narrow
the second source to prevent overwriting data we still need. Similar
when the destination is equal to the first source.
Bug b/37496082
Change-Id: I908a8e125a77ec4bf1eb5eab9e48c6112ee4ca13
Reviewed-on: https://chromium-review.googlesource.com/696032
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
Reviewed-on: https://swiftshader-review.googlesource.com/12949
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/third_party/subzero/src/IceAssemblerARM32.cpp b/third_party/subzero/src/IceAssemblerARM32.cpp
index a8e9021..502668c 100644
--- a/third_party/subzero/src/IceAssemblerARM32.cpp
+++ b/third_party/subzero/src/IceAssemblerARM32.cpp
@@ -3731,16 +3731,15 @@
VqmovnOpcode |= (encodeElmtType(DestElmtTy) << ElmtShift);
if (Qm != Qd) {
- // Narrow first source operand to lower half of destination.
- emitSIMDBase(VqmovnOpcode, Dd + 0, 0, Dm, UseQRegs, IsFloatTy);
// Narrow second source operand to upper half of destination.
emitSIMDBase(VqmovnOpcode, Dd + 1, 0, Dn, UseQRegs, IsFloatTy);
+ // Narrow first source operand to lower half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 0, 0, Dm, UseQRegs, IsFloatTy);
} else if (Qn != Qd) {
- // Narrow second source operand to upper half of destination.
- emitSIMDBase(VqmovnOpcode, Dd + 1, 0, Dn, UseQRegs, IsFloatTy);
// Narrow first source operand to lower half of destination.
emitSIMDBase(VqmovnOpcode, Dd + 0, 0, Dm, UseQRegs, IsFloatTy);
-
+ // Narrow second source operand to upper half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 1, 0, Dn, UseQRegs, IsFloatTy);
} else {
// Narrow first source operand to lower half of destination.
emitSIMDBase(VqmovnOpcode, Dd, 0, Dm, UseQRegs, IsFloatTy);