aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-03-11 02:49:12 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-03-11 02:49:12 +0000
commit24645f8955c024aca43953ef941ebf3bc6f155bb (patch)
tree081dc66306c6d3805777dc7a92b200fcc09630ad
parent742f86daa4e3d7e1c5a8a536d8681a8209e670d8 (diff)
parent32d18870057599c8218ac5e5e4b2c300df10375a (diff)
downloadvixl-24645f8955c024aca43953ef941ebf3bc6f155bb.tar.gz
Merge "[sve] Fix while simulation corner case" am: 32d1887005
Original change: https://android-review.googlesource.com/c/platform/external/vixl/+/1596671 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Icecd39efbd5de9815a4e9b340fea642ab64d5881
-rw-r--r--src/aarch64/simulator-aarch64.cc22
-rw-r--r--test/aarch64/test-assembler-sve-aarch64.cc18
2 files changed, 33 insertions, 7 deletions
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index cae59b21..04f1165d 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -8964,25 +8964,33 @@ void Simulator::VisitSVEIntCompareScalarCountAndLimit(
unsigned rm_code = instr->GetRm();
SimPRegister& pd = ReadPRegister(instr->GetPd());
VectorFormat vform = instr->GetSVEVectorFormat();
+
bool is_64_bit = instr->ExtractBit(12) == 1;
- int64_t src1 = is_64_bit ? ReadXRegister(rn_code) : ReadWRegister(rn_code);
- int64_t src2 = is_64_bit ? ReadXRegister(rm_code) : ReadWRegister(rm_code);
+ int rsize = is_64_bit ? kXRegSize : kWRegSize;
+ uint64_t mask = is_64_bit ? kXRegMask : kWRegMask;
+
+ uint64_t usrc1 = ReadXRegister(rn_code);
+ int64_t ssrc2 = is_64_bit ? ReadXRegister(rm_code) : ReadWRegister(rm_code);
+ uint64_t usrc2 = ssrc2 & mask;
bool last = true;
for (int lane = 0; lane < LaneCountFromFormat(vform); lane++) {
+ usrc1 &= mask;
+ int64_t ssrc1 = ExtractSignedBitfield64(rsize - 1, 0, usrc1);
+
bool cond = false;
switch (instr->Mask(SVEIntCompareScalarCountAndLimitMask)) {
case WHILELE_p_p_rr:
- cond = src1 <= src2;
+ cond = ssrc1 <= ssrc2;
break;
case WHILELO_p_p_rr:
- cond = static_cast<uint64_t>(src1) < static_cast<uint64_t>(src2);
+ cond = usrc1 < usrc2;
break;
case WHILELS_p_p_rr:
- cond = static_cast<uint64_t>(src1) <= static_cast<uint64_t>(src2);
+ cond = usrc1 <= usrc2;
break;
case WHILELT_p_p_rr:
- cond = src1 < src2;
+ cond = ssrc1 < ssrc2;
break;
default:
VIXL_UNIMPLEMENTED();
@@ -8991,7 +8999,7 @@ void Simulator::VisitSVEIntCompareScalarCountAndLimit(
last = last && cond;
LogicPRegister dst(pd);
dst.SetActive(vform, lane, last);
- src1 += 1;
+ usrc1++;
}
PredTest(vform, GetPTrue(), pd);
diff --git a/test/aarch64/test-assembler-sve-aarch64.cc b/test/aarch64/test-assembler-sve-aarch64.cc
index 7f0c178b..61583143 100644
--- a/test/aarch64/test-assembler-sve-aarch64.cc
+++ b/test/aarch64/test-assembler-sve-aarch64.cc
@@ -2551,6 +2551,24 @@ TEST(sve_int_compare_count_and_limit_scalars) {
}
}
+TEST(sve_int_compare_count_and_limit_scalars_regression_test) {
+ SETUP_WITH_FEATURES(CPUFeatures::kSVE);
+ START();
+
+ __ Mov(w0, 0x7ffffffd);
+ __ Mov(w1, 0x7fffffff);
+ __ Whilele(p0.VnB(), w0, w1);
+
+ END();
+
+ if (CAN_RUN()) {
+ RUN();
+
+ int p0_expected[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+ ASSERT_EQUAL_SVE(p0_expected, p0.VnB());
+ }
+}
+
TEST(sve_int_compare_vectors_signed_imm) {
SETUP_WITH_FEATURES(CPUFeatures::kSVE);
START();