Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1634)

Unified Diff: test/cctest/compiler/test-gap-resolver.cc

Issue 2410673002: [Turbofan] Add concept of FP register aliasing on ARM 32. (Closed)
Patch Set: Add a TODO. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/zone/zone-allocator.h ('k') | test/cctest/compiler/test-run-native-calls.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/compiler/test-gap-resolver.cc
diff --git a/test/cctest/compiler/test-gap-resolver.cc b/test/cctest/compiler/test-gap-resolver.cc
index 3b1cdb6d814fd1274bb9180d877c302b27a7c683..1cceb9cd59a3bc40225bdaba98e897e8c94f0b5f 100644
--- a/test/cctest/compiler/test-gap-resolver.cc
+++ b/test/cctest/compiler/test-gap-resolver.cc
@@ -13,15 +13,32 @@ namespace compiler {
const auto GetRegConfig = RegisterConfiguration::Turbofan;
-// Fragments the given operand into an equivalent set of operands to simplify
-// ParallelMove equivalence testing.
+// Fragments the given FP operand into an equivalent set of FP operands to
+// simplify ParallelMove equivalence testing.
void GetCanonicalOperands(const InstructionOperand& op,
std::vector<InstructionOperand>* fragments) {
CHECK(!kSimpleFPAliasing);
CHECK(op.IsFPLocationOperand());
- // TODO(bbudge) Split into float operands on platforms with non-simple FP
- // register aliasing.
- fragments->push_back(op);
+ const LocationOperand& loc = LocationOperand::cast(op);
+ MachineRepresentation rep = loc.representation();
+ int base = -1;
+ int aliases = GetRegConfig()->GetAliases(
+ rep, 0, MachineRepresentation::kFloat32, &base);
+ CHECK_LT(0, aliases);
+ CHECK_GE(4, aliases);
+ int index = -1;
+ int step = 1;
+ if (op.IsFPRegister()) {
+ index = loc.register_code() * aliases;
+ } else {
+ index = loc.index();
+ step = -1;
+ }
+ for (int i = 0; i < aliases; i++) {
+ fragments->push_back(AllocatedOperand(loc.location_kind(),
+ MachineRepresentation::kFloat32,
+ index + i * step));
+ }
}
// The state of our move interpreter is the mapping of operands to values. Note
@@ -36,7 +53,9 @@ class InterpreterState {
const InstructionOperand& dst = m->destination();
if (!kSimpleFPAliasing && src.IsFPLocationOperand() &&
dst.IsFPLocationOperand()) {
- // Canonicalize FP location-location moves.
+ // Canonicalize FP location-location moves by fragmenting them into
+ // an equivalent sequence of float32 moves, to simplify state
+ // equivalence testing.
std::vector<InstructionOperand> src_fragments;
GetCanonicalOperands(src, &src_fragments);
CHECK(!src_fragments.empty());
@@ -115,9 +134,11 @@ class InterpreterState {
int index;
if (!is_constant) {
const LocationOperand& loc_op = LocationOperand::cast(op);
- // Canonicalize FP location operand representations to kFloat64.
+ // Preserve FP representation when FP register aliasing is complex.
+ // Otherwise, canonicalize to kFloat64.
if (IsFloatingPoint(loc_op.representation())) {
- rep = MachineRepresentation::kFloat64;
+ rep = kSimpleFPAliasing ? MachineRepresentation::kFloat64
+ : loc_op.representation();
}
if (loc_op.IsAnyRegister()) {
index = loc_op.register_code();
@@ -321,9 +342,11 @@ class ParallelMoveCreator : public HandleAndZoneScope {
auto GetValidRegisterCode = [&conf](MachineRepresentation rep, int index) {
switch (rep) {
case MachineRepresentation::kFloat32:
+ return conf->RegisterConfiguration::GetAllocatableFloatCode(index);
case MachineRepresentation::kFloat64:
- case MachineRepresentation::kSimd128:
return conf->RegisterConfiguration::GetAllocatableDoubleCode(index);
+ case MachineRepresentation::kSimd128:
+ return conf->RegisterConfiguration::GetAllocatableSimd128Code(index);
default:
return conf->RegisterConfiguration::GetAllocatableGeneralCode(index);
}
@@ -368,6 +391,118 @@ void RunTest(ParallelMove* pm, Zone* zone) {
CHECK_EQ(mi1.state(), mi2.state());
}
+TEST(Aliasing) {
+ // On platforms with simple aliasing, these parallel moves are ill-formed.
+ if (kSimpleFPAliasing) return;
+
+ ParallelMoveCreator pmc;
+ Zone* zone = pmc.main_zone();
+
+ auto s0 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat32, 0);
+ auto s1 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat32, 1);
+ auto s2 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat32, 2);
+ auto s3 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat32, 3);
+ auto s4 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat32, 4);
+
+ auto d0 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat64, 0);
+ auto d1 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat64, 1);
+ auto d16 = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kFloat64, 16);
+
+ // Double slots must be odd to match frame allocation.
+ auto dSlot = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kFloat64, 3);
+
+ // Cycles involving s- and d-registers.
+ {
+ std::vector<InstructionOperand> moves = {
+ s2, s0, // s2 <- s0
+ d0, d1 // d0 <- d1
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ {
+ std::vector<InstructionOperand> moves = {
+ d0, d1, // d0 <- d1
+ s2, s0 // s2 <- s0
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ {
+ std::vector<InstructionOperand> moves = {
+ s2, s1, // s2 <- s1
+ d0, d1 // d0 <- d1
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ {
+ std::vector<InstructionOperand> moves = {
+ d0, d1, // d0 <- d1
+ s2, s1 // s2 <- s1
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Two cycles involving a single d-register.
+ {
+ std::vector<InstructionOperand> moves = {
+ d0, d1, // d0 <- d1
+ s2, s1, // s2 <- s1
+ s3, s0 // s3 <- s0
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Cycle with a float move that must be deferred until after swaps.
+ {
+ std::vector<InstructionOperand> moves = {
+ d0, d1, // d0 <- d1
+ s2, s0, // s2 <- s0
+ s3, s4 // s3 <- s4 must be deferred
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Cycles involving s-registers and a non-aliased d-register.
+ {
+ std::vector<InstructionOperand> moves = {
+ d16, d0, // d16 <- d0
+ s1, s2, // s1 <- s2
+ d1, d16 // d1 <- d16
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ {
+ std::vector<InstructionOperand> moves = {
+ s2, s1, // s1 <- s2
+ d0, d16, // d16 <- d0
+ d16, d1 // d1 <- d16
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ {
+ std::vector<InstructionOperand> moves = {
+ d0, d16, // d0 <- d16
+ d16, d1, // s2 <- s0
+ s3, s0 // d0 <- d1
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Cycle involving aliasing registers and a slot.
+ {
+ std::vector<InstructionOperand> moves = {
+ dSlot, d0, // dSlot <- d0
+ d1, dSlot, // d1 <- dSlot
+ s0, s3 // s0 <- s3
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+}
+
TEST(FuzzResolver) {
ParallelMoveCreator pmc;
for (int size = 0; size < 80; ++size) {
« no previous file with comments | « src/zone/zone-allocator.h ('k') | test/cctest/compiler/test-run-native-calls.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698