This fixes an issue in vmv.s.x where the destination vector was cleared before the scalar element was written to element 0. Now the remainder of the vector stays unchanged. PiperOrigin-RevId: 708376070 Change-Id: Ided3a433ac238859a9102008e8d94315dbe639e2
diff --git a/riscv/riscv_vector_unary_instructions.cc b/riscv/riscv_vector_unary_instructions.cc index c6fc407..318ad24 100644 --- a/riscv/riscv_vector_unary_instructions.cc +++ b/riscv/riscv_vector_unary_instructions.cc
@@ -15,10 +15,7 @@ #include "riscv/riscv_vector_unary_instructions.h" #include <cstdint> -#include <cstring> #include <functional> -#include <optional> -#include <type_traits> #include "absl/log/log.h" #include "absl/strings/str_cat.h" @@ -77,8 +74,7 @@ if (rv_vector->vstart()) return; if (rv_vector->vector_length() == 0) return; int sew = rv_vector->selected_element_width(); - auto *dest_db = inst->Destination(0)->AllocateDataBuffer(); - std::memset(dest_db->raw_ptr(), 0, dest_db->size<uint8_t>()); + auto *dest_db = inst->Destination(0)->CopyDataBuffer(); switch (sew) { case 1: dest_db->Set<int8_t>(0, generic::GetInstructionSource<int8_t>(inst, 0));
diff --git a/riscv/test/riscv_vector_unary_instructions_test.cc b/riscv/test/riscv_vector_unary_instructions_test.cc index db3e21e..8ff9f2c 100644 --- a/riscv/test/riscv_vector_unary_instructions_test.cc +++ b/riscv/test/riscv_vector_unary_instructions_test.cc
@@ -160,6 +160,23 @@ ConfigureVectorUnit(vtype, vlen); // Test 10 different values. for (int i = 0; i < 10; i++) { + // Set the vector register to known values. + for (int v = 0; v < vlen; v++) { + switch (byte_sew) { + case 1: + vreg_[kVs2]->data_buffer()->Set<int8_t>(v, v); + break; + case 2: + vreg_[kVs2]->data_buffer()->Set<int16_t>(v, v); + break; + case 4: + vreg_[kVs2]->data_buffer()->Set<int32_t>(v, v); + break; + case 8: + vreg_[kVs2]->data_buffer()->Set<int64_t>(v, v); + break; + } + } auto value = RandomValue<SignedXregType>(); SetRegisterValues<SignedXregType>({{kRs1Name, value}}); instruction_->Execute(); @@ -167,18 +184,30 @@ case 1: EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int8_t>(0), static_cast<int8_t>(value)); + for (int v = 1; v < vlen; v++) { + EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int8_t>(v), v); + } break; case 2: EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int16_t>(0), static_cast<int16_t>(value)); + for (int v = 1; v < vlen; v++) { + EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int16_t>(v), v); + } break; case 4: EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int32_t>(0), static_cast<int32_t>(value)); + for (int v = 1; v < vlen; v++) { + EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int32_t>(v), v); + } break; case 8: EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int64_t>(0), static_cast<int64_t>(value)); + for (int v = 1; v < vlen; v++) { + EXPECT_EQ(vreg_[kVs2]->data_buffer()->Get<int64_t>(v), v); + } break; } }