diff options
author | Aart Bik <ajcbik@google.com> | 2015-10-09 11:15:55 -0700 |
---|---|---|
committer | Aart Bik <ajcbik@google.com> | 2015-10-14 13:38:22 -0700 |
commit | e9f37600e98ba21308ad4f70d9d68cf6c057bdbe (patch) | |
tree | ad7953f41a35eeee68a31b4b567a08c650647bba /compiler/optimizing/codegen_test.cc | |
parent | 793e6fbdefb092d1dab50bca5618aed110c7e037 (diff) |
Added support for unsigned comparisons
Rationale: even though not directly supported in input graph,
having the ability to express unsigned comparisons
in HIR is useful for all sorts of optimizations.
Change-Id: I4543c96a8c1895c3d33aaf85685afbf80fe27d72
Diffstat (limited to 'compiler/optimizing/codegen_test.cc')
-rw-r--r-- | compiler/optimizing/codegen_test.cc | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc index 22f227c56a..fe5af2fc5e 100644 --- a/compiler/optimizing/codegen_test.cc +++ b/compiler/optimizing/codegen_test.cc @@ -761,4 +761,130 @@ TEST(CodegenTest, ReturnDivInt2Addr) { TestCode(data, true, 2); } +// Helper method. +static void TestComparison(IfCondition condition, int64_t i, int64_t j, Primitive::Type type) { + ArenaPool pool; + ArenaAllocator allocator(&pool); + HGraph* graph = CreateGraph(&allocator); + + HBasicBlock* entry_block = new (&allocator) HBasicBlock(graph); + graph->AddBlock(entry_block); + graph->SetEntryBlock(entry_block); + entry_block->AddInstruction(new (&allocator) HGoto()); + + HBasicBlock* block = new (&allocator) HBasicBlock(graph); + graph->AddBlock(block); + + HBasicBlock* exit_block = new (&allocator) HBasicBlock(graph); + graph->AddBlock(exit_block); + graph->SetExitBlock(exit_block); + exit_block->AddInstruction(new (&allocator) HExit()); + + entry_block->AddSuccessor(block); + block->AddSuccessor(exit_block); + + HInstruction* op1; + HInstruction* op2; + if (type == Primitive::kPrimInt) { + op1 = graph->GetIntConstant(i); + op2 = graph->GetIntConstant(j); + } else { + DCHECK_EQ(type, Primitive::kPrimLong); + op1 = graph->GetLongConstant(i); + op2 = graph->GetLongConstant(j); + } + + HInstruction* comparison = nullptr; + bool expected_result = false; + const uint64_t x = i; + const uint64_t y = j; + switch (condition) { + case kCondEQ: + comparison = new (&allocator) HEqual(op1, op2); + expected_result = (i == j); + break; + case kCondNE: + comparison = new (&allocator) HNotEqual(op1, op2); + expected_result = (i != j); + break; + case kCondLT: + comparison = new (&allocator) HLessThan(op1, op2); + expected_result = (i < j); + break; + case kCondLE: + comparison = new (&allocator) HLessThanOrEqual(op1, op2); + expected_result = (i <= j); + break; + case kCondGT: + comparison = new (&allocator) HGreaterThan(op1, op2); + expected_result = (i > j); + break; + case kCondGE: + comparison = new (&allocator) HGreaterThanOrEqual(op1, op2); + expected_result = (i >= j); + break; + case kCondB: + comparison = new (&allocator) HBelow(op1, op2); + expected_result = (x < y); + break; + case kCondBE: + comparison = new (&allocator) HBelowOrEqual(op1, op2); + expected_result = (x <= y); + break; + case kCondA: + comparison = new (&allocator) HAbove(op1, op2); + expected_result = (x > y); + break; + case kCondAE: + comparison = new (&allocator) HAboveOrEqual(op1, op2); + expected_result = (x >= y); + break; + } + block->AddInstruction(comparison); + block->AddInstruction(new (&allocator) HReturn(comparison)); + + auto hook_before_codegen = [](HGraph*) { + }; + RunCodeOptimized(graph, hook_before_codegen, true, expected_result); +} + +TEST(CodegenTest, ComparisonsInt) { + for (int64_t i = -1; i <= 1; i++) { + for (int64_t j = -1; j <= 1; j++) { + TestComparison(kCondEQ, i, j, Primitive::kPrimInt); + TestComparison(kCondNE, i, j, Primitive::kPrimInt); + TestComparison(kCondLT, i, j, Primitive::kPrimInt); + TestComparison(kCondLE, i, j, Primitive::kPrimInt); + TestComparison(kCondGT, i, j, Primitive::kPrimInt); + TestComparison(kCondGE, i, j, Primitive::kPrimInt); + TestComparison(kCondB, i, j, Primitive::kPrimInt); + TestComparison(kCondBE, i, j, Primitive::kPrimInt); + TestComparison(kCondA, i, j, Primitive::kPrimInt); + TestComparison(kCondAE, i, j, Primitive::kPrimInt); + } + } +} + +TEST(CodegenTest, ComparisonsLong) { + // TODO: make MIPS work for long + if (kRuntimeISA == kMips || kRuntimeISA == kMips64) { + return; + } + + for (int64_t i = -1; i <= 1; i++) { + for (int64_t j = -1; j <= 1; j++) { + TestComparison(kCondEQ, i, j, Primitive::kPrimLong); + TestComparison(kCondNE, i, j, Primitive::kPrimLong); + TestComparison(kCondLT, i, j, Primitive::kPrimLong); + TestComparison(kCondLE, i, j, Primitive::kPrimLong); + TestComparison(kCondGT, i, j, Primitive::kPrimLong); + TestComparison(kCondGE, i, j, Primitive::kPrimLong); + TestComparison(kCondB, i, j, Primitive::kPrimLong); + TestComparison(kCondBE, i, j, Primitive::kPrimLong); + TestComparison(kCondA, i, j, Primitive::kPrimLong); + TestComparison(kCondAE, i, j, Primitive::kPrimLong); + } + } +} + } // namespace art |