Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Z codegen does not handle sub-integer compares as the first child of an integral select node #5499

Open
aviansie-ben opened this issue Aug 27, 2020 · 5 comments

Comments

@aviansie-ben
Copy link
Contributor

As part of refactoring the *select evaluators on Power in #5497, new Tril tests were added to exercise previously untested codegen optimizations for when the first child is a compare. When running these tests on Z, the following assertion was observed in SelectCompareTest/Int32SelectInt8CompareTest:

[2020-08-26T22:12:15.873Z] 29: Assertion failed at /home/jenkins/workspace/Build/compiler/z/codegen/ControlFlowEvaluator.cpp:2473: 0
[2020-08-26T22:12:15.873Z] 29: 	Unhandled compare node type
[2020-08-26T22:12:15.873Z] 29: 
[2020-08-26T22:12:15.873Z] 29: compiling file:line:name at level: warm
[2020-08-26T22:12:15.873Z] 29: #0: function TR_LinuxCallStackIterator::printStackBacktrace(TR::Compilation*)+0x42 [0x81d61aa2]
[2020-08-26T22:12:15.873Z] 29: #1: function TR_Debug::printStackBacktrace()+0x38 [0x81a5e1f0]
[2020-08-26T22:12:15.873Z] 29: #2: /home/jenkins/workspace/Build/build/fvtest/compilertriltest/comptest() [0x81816afa]
[2020-08-26T22:12:15.873Z] 29: #3: /home/jenkins/workspace/Build/build/fvtest/compilertriltest/comptest() [0x81816c40]
[2020-08-26T22:12:15.873Z] 29: #4: function TR::assertion(char const*, int, char const*, char const*, ...)+0x10a [0x81816d52]
[2020-08-26T22:12:15.873Z] 29: #5: function OMR::Z::TreeEvaluator::getCompareOpFromNode(TR::CodeGenerator*, TR::Node*)+0x284 [0x81d8adbc]
[2020-08-26T22:12:15.873Z] 29: #6: function OMR::Z::TreeEvaluator::selectEvaluator(TR::Node*, TR::CodeGenerator*)+0x4cc [0x81d8b594]
[2020-08-26T22:12:15.873Z] 29: #7: function OMR::CodeGenerator::evaluate(TR::Node*)+0x1ee [0x81af5376]
[2020-08-26T22:12:15.873Z] 29: #8: function OMR::Z::TreeEvaluator::returnEvaluator(TR::Node*, TR::CodeGenerator*)+0x134 [0x81d84aec]
[2020-08-26T22:12:15.873Z] 29: #9: function OMR::CodeGenerator::evaluate(TR::Node*)+0x1ee [0x81af5376]
[2020-08-26T22:12:15.873Z] 29: #10: function OMR::CodeGenerator::doInstructionSelection()+0x64e [0x81af9cb6]
[2020-08-26T22:12:15.873Z] 29: #11: function OMR::Z::CodeGenerator::doInstructionSelection()+0x26 [0x81aa53a6]
[2020-08-26T22:12:15.873Z] 29: #12: function OMR::CodeGenPhase::performInstructionSelectionPhase(TR::CodeGenerator*, TR::CodeGenPhase*)+0x112 [0x81b0c5a2]
[2020-08-26T22:12:15.873Z] 29: #13: function OMR::CodeGenPhase::performAll()+0x182 [0x81b0adda]
[2020-08-26T22:12:15.873Z] 29: #14: function OMR::CodeGenerator::generateCode()+0xe8 [0x81afca28]
[2020-08-26T22:12:15.873Z] 29: #15: function OMR::Compilation::compile()+0xe00 [0x81720320]
[2020-08-26T22:12:15.873Z] 29: #16: function compileMethodFromDetails(OMR_VMThread*, TR::IlGeneratorMethodDetails&, TR_Hotness, int&)+0x798 [0x8174e100]
[2020-08-26T22:12:15.873Z] 29: #17: function Tril::SimpleCompiler::compileWithVerifier(TR::IlVerifier*)+0x3c4 [0x8167ad3c]
[2020-08-26T22:12:15.873Z] 29: #18: function Tril::SimpleCompiler::compile()+0x26 [0x8167a95e]
[2020-08-26T22:12:15.873Z] 29: #19: function Int32SelectInt8CompareTest_UsingLoadParam_Test::TestBody()+0x304 [0x81578b04]
[2020-08-26T22:12:15.873Z] 29: #20: function void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*)+0x78 [0x816c5ef0]
[2020-08-26T22:12:15.873Z] 29: #21: function void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*)+0x72 [0x816be072]
[2020-08-26T22:12:15.873Z] 29: #22: function testing::Test::Run()+0x104 [0x8169943c]
[2020-08-26T22:12:15.873Z] 29: #23: function testing::TestInfo::Run()+0x15a [0x81699f82]
[2020-08-26T22:12:15.873Z] 29: #24: function testing::TestCase::Run()+0x13c [0x8169a924]
[2020-08-26T22:12:15.873Z] 29: #25: function testing::internal::UnitTestImpl::RunAllTests()+0x394 [0x816a3acc]
[2020-08-26T22:12:15.873Z] 29: #26: function bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*)+0x78 [0x816c7350]
[2020-08-26T22:12:15.873Z] 29: #27: function bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*)+0x72 [0x816bf4a2]
[2020-08-26T22:12:15.873Z] 29: #28: function testing::UnitTest::Run()+0xe0 [0x816a2158]
[2020-08-26T22:12:15.873Z] 29: #29: function RUN_ALL_TESTS()+0x24 [0x80f9682c]

From looking at the code, it appears that the Z codegen's evaluator for integral select nodes has an optimization for when the first child is a compare node, but it does not handle Int8 or Int16 compares even though Z does have evaluators for these opcodes.

@Spencer-Comin
Copy link
Contributor

@r30shah and I looked into this today. This might be more hairy to fix than expected.

Address "Unhandled compare node type" assert

Patch

diff --git a/compiler/z/codegen/ControlFlowEvaluator.cpp b/compiler/z/codegen/ControlFlowEvaluator.cpp
index be2ff651f..0bda5fbce 100644
--- a/compiler/z/codegen/ControlFlowEvaluator.cpp
+++ b/compiler/z/codegen/ControlFlowEvaluator.cpp
@@ -2410,7 +2422,7 @@ TR::InstOpCode::Mnemonic OMR::Z::TreeEvaluator::getCompareOpFromNode(TR::CodeGen
          return TR::InstOpCode::CGR;
          }
       }
-   else if (node->getFirstChild()->getSize() == 4)
+   else
       {
       if (node->getOpCode().isUnsigned())
          {
@@ -2421,10 +2433,6 @@ TR::InstOpCode::Mnemonic OMR::Z::TreeEvaluator::getCompareOpFromNode(TR::CodeGen
          return TR::InstOpCode::CR;
          }
       }
-
-   TR_ASSERT(0, "Unhandled compare node type\n");
-   return TR::InstOpCode::CR;
-
    }

The original failing assert is hit here when node->getFirstChild()->getSize() evaluates to 2 or 1. 2 or 1 byte values will be extended to 4 bytes when in registers, so they can be treated the same as 4 byte values. This eliminates the need for this assert.

Result

spencer@zbox:omr/build/fvtest/compilertriltest$ ./comptest --gtest_filter=SelectCompareTest*
Note: Google Test filter = SelectCompareTest*
[==========] Running 5130 tests from 11 test cases.
[----------] 450 tests from SelectCompareTest/Int8SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int8SelectInt32CompareTest (679 ms total)

[----------] 450 tests from SelectCompareTest/Int16SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int16SelectInt32CompareTest (737 ms total)

[----------] 450 tests from SelectCompareTest/Int32SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int32SelectInt32CompareTest (675 ms total)

[----------] 450 tests from SelectCompareTest/Int64SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int64SelectInt32CompareTest (820 ms total)

[----------] 450 tests from SelectCompareTest/FloatSelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/FloatSelectInt32CompareTest (796 ms total)

[----------] 450 tests from SelectCompareTest/DoubleSelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/DoubleSelectInt32CompareTest (808 ms total)

[----------] 450 tests from SelectCompareTest/Int32SelectInt8CompareTest
Assertion failed at /jit/team/spencer/omr/compiler/z/codegen/ControlFlowEvaluator.cpp:2343: 0
	Unsupported compare type under select
compiling file:line:name at level: warm
#0: ./comptest(_ZN25TR_LinuxCallStackIterator19printStackBacktraceEPN2TR11CompilationE+0x56) [0x2aa32abcdbe]
#1: ./comptest(_ZN8TR_Debug19printStackBacktraceEv+0x4c) [0x2aa3279e564]
#2: ./comptest(+0x1a4b846) [0x2aa3254b846]
#3: ./comptest(+0x1a4b9b8) [0x2aa3254b9b8]
#4: ./comptest(+0x1a4bbb8) [0x2aa3254bbb8]
#5: ./comptest(_ZN3OMR1Z13TreeEvaluator35getBranchConditionFromCompareOpCodeEN2TR9ILOpCodesE+0x92) [0x2aa32ae4512]
#6: ./comptest(_ZN3OMR1Z13TreeEvaluator15selectEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x75a) [0x2aa32ae52a2]
#7: ./comptest(_ZN3OMR1Z13TreeEvaluator16iselectEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x2e) [0x2aa32b9d74e]
#8: ./comptest(_ZN3OMR13CodeGenerator8evaluateEPN2TR4NodeE+0x222) [0x2aa3283239a]
#9: ./comptest(_ZN3OMR1Z13TreeEvaluator15returnEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x13e) [0x2aa32ade39e]
#10: ./comptest(_ZN3OMR1Z13TreeEvaluator16ireturnEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x2e) [0x2aa32b9af5e]
#11: ./comptest(_ZN3OMR13CodeGenerator8evaluateEPN2TR4NodeE+0x222) [0x2aa3283239a]
#12: ./comptest(_ZN3OMR13CodeGenerator22doInstructionSelectionEv+0x598) [0x2aa32836df8]
#13: ./comptest(_ZN3OMR1Z13CodeGenerator22doInstructionSelectionEv+0x26) [0x2aa327e4a8e]
#14: ./comptest(_ZN3OMR12CodeGenPhase32performInstructionSelectionPhaseEPN2TR13CodeGeneratorEPNS1_12CodeGenPhaseE+0x12a) [0x2aa3284b76a]
#15: ./comptest(_ZN3OMR12CodeGenPhase10performAllEv+0x1d8) [0x2aa32849e20]
#16: ./comptest(_ZN3OMR13CodeGenerator12generateCodeEv+0x104) [0x2aa3283a0f4]
#17: ./comptest(_ZN3OMR11Compilation7compileEv+0xe3e) [0x2aa3244eb56]
#18: ./comptest(_Z24compileMethodFromDetailsP12OMR_VMThreadRN2TR24IlGeneratorMethodDetailsE10TR_HotnessRi+0x7da) [0x2aa32480c62]
#19: ./comptest(_ZN4Tril14SimpleCompiler19compileWithVerifierEPN2TR10IlVerifierE+0x400) [0x2aa323a45c8]
#20: ./comptest(_ZN4Tril14SimpleCompiler7compileEv+0x26) [0x2aa323a41ae]
#21: ./comptest(_ZN46Int32SelectInt8CompareTest_UsingLoadParam_Test8TestBodyEv+0x500) [0x2aa3228bb70]
#22: ./comptest(_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x84) [0x2aa323f4d3c]
#23: ./comptest(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x8c) [0x2aa323ec6ac]
#24: ./comptest(_ZN7testing4Test3RunEv+0x100) [0x2aa323c4e20]
#25: ./comptest(_ZN7testing8TestInfo3RunEv+0x15a) [0x2aa323c5a62]
#26: ./comptest(_ZN7testing8TestCase3RunEv+0x162) [0x2aa323c645a]
#27: ./comptest(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+0x402) [0x2aa323d0152]
#28: ./comptest(_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc+0x84) [0x2aa323f670c]
#29: ./comptest(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc+0x8c) [0x2aa323edbb4]

Trace/breakpoint trap (core dumped)

Another assert hit

Address "Unsupported compare type under select" assert

Patch

diff --git a/compiler/z/codegen/ControlFlowEvaluator.cpp b/compiler/z/codegen/ControlFlowEvaluator.cpp
index be2ff651f..0bda5fbce 100644
--- a/compiler/z/codegen/ControlFlowEvaluator.cpp
+++ b/compiler/z/codegen/ControlFlowEvaluator.cpp
@@ -2292,6 +2292,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
    {
    switch (opCode)
       {
+      case TR::bcmpeq:
+      case TR::scmpeq:
       case TR::icmpeq:
       case TR::acmpeq:
       case TR::lcmpeq:
@@ -2299,6 +2301,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
          return TR::InstOpCode::COND_BE;
       case TR::lcmpne:
@@ -2306,6 +2310,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
          return TR::InstOpCode::COND_BNE;
          }
          break;
+      case TR::bcmplt:
+      case TR::scmplt:
       case TR::icmplt:
       case TR::iucmplt:
       case TR::lcmplt:
@@ -2314,6 +2320,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
          return TR::InstOpCode::COND_BL;
          }
          break;
+      case TR::bcmple:
+      case TR::scmple:
       case TR::icmple:
       case TR::iucmple:
       case TR::lcmple:
@@ -2322,6 +2330,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
          return TR::InstOpCode::COND_BNH;
          }
          break;
+      case TR::bcmpgt:
+      case TR::scmpgt:
       case TR::icmpgt:
       case TR::iucmpgt:
       case TR::lcmpgt:
@@ -2330,6 +2340,8 @@ TR::InstOpCode::S390BranchCondition OMR::Z::TreeEvaluator::getBranchConditionFro
          return TR::InstOpCode::COND_BH;
          }
          break;
+      case TR::bcmpge:
+      case TR::scmpge:
       case TR::icmpge:
       case TR::iucmpge:
       case TR::lcmpge:

Addressing this assert is a simple fix; it appears that the byte and short opcodes were left out of the switch statement and simply needed adding in.

Result

spencer@zbox:omr/build/fvtest/compilertriltest$ ./comptest --gtest_filter=SelectCompareTest*
Note: Google Test filter = SelectCompareTest*
[==========] Running 5130 tests from 11 test cases.
[----------] 450 tests from SelectCompareTest/Int8SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int8SelectInt32CompareTest (702 ms total)

[----------] 450 tests from SelectCompareTest/Int16SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int16SelectInt32CompareTest (834 ms total)

[----------] 450 tests from SelectCompareTest/Int32SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int32SelectInt32CompareTest (627 ms total)

[----------] 450 tests from SelectCompareTest/Int64SelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/Int64SelectInt32CompareTest (673 ms total)

[----------] 450 tests from SelectCompareTest/FloatSelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/FloatSelectInt32CompareTest (641 ms total)

[----------] 450 tests from SelectCompareTest/DoubleSelectInt32CompareTest
[----------] 450 tests from SelectCompareTest/DoubleSelectInt32CompareTest (647 ms total)

[----------] 450 tests from SelectCompareTest/Int32SelectInt8CompareTest
Assertion failed at /jit/team/spencer/omr/compiler/z/codegen/OMRTreeEvaluator.cpp:5086: 0
	generateS390CompareOps: Unexpected child type (Int8) with size = 1

compiling file:line:name at level: warm
#0: ./comptest(_ZN25TR_LinuxCallStackIterator19printStackBacktraceEPN2TR11CompilationE+0x56) [0x2aa3263cdbe]
#1: ./comptest(_ZN8TR_Debug19printStackBacktraceEv+0x4c) [0x2aa3231e564]
#2: ./comptest(+0x1a4b846) [0x2aa320cb846]
#3: ./comptest(+0x1a4b9b8) [0x2aa320cb9b8]
#4: ./comptest(+0x1a4bbb8) [0x2aa320cbbb8]
#5: ./comptest(_Z37generateS390CompareAndBranchOpsHelperPN2TR4NodeEPNS_13CodeGeneratorEN3OMR1Z10InstOpCode19S390BranchConditionES7_RS7_PNS_11LabelSymbolE+0x1d28) [0x2aa3272ae70]
#6: ./comptest(_Z22generateS390CompareOpsPN2TR4NodeEPNS_13CodeGeneratorEN3OMR1Z10InstOpCode19S390BranchConditionES7_PNS_11LabelSymbolE+0x86) [0x2aa3272b1ce]
#7: ./comptest(_Z23generateS390CompareBoolPN2TR4NodeEPNS_13CodeGeneratorEN3OMR10InstOpCode8MnemonicENS4_1Z10InstOpCode19S390BranchConditionES9_b+0x230) [0x2aa3272b440]
#8: ./comptest(_ZN3OMR1Z13TreeEvaluator15icmpltEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x2ec) [0x2aa32660754]
#9: ./comptest(_ZN3OMR1Z13TreeEvaluator15bcmpltEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x2e) [0x2aa32660e46]
#10: ./comptest(_ZN3OMR13CodeGenerator8evaluateEPN2TR4NodeE+0x222) [0x2aa323b239a]
#11: ./comptest(_ZN3OMR1Z13TreeEvaluator15returnEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x13e) [0x2aa3265e39e]
#12: ./comptest(_ZN3OMR1Z13TreeEvaluator16ireturnEvaluatorEPN2TR4NodeEPNS2_13CodeGeneratorE+0x2e) [0x2aa3271af5e]
#13: ./comptest(_ZN3OMR13CodeGenerator8evaluateEPN2TR4NodeE+0x222) [0x2aa323b239a]
#14: ./comptest(_ZN3OMR13CodeGenerator22doInstructionSelectionEv+0x598) [0x2aa323b6df8]
#15: ./comptest(_ZN3OMR1Z13CodeGenerator22doInstructionSelectionEv+0x26) [0x2aa32364a8e]
#16: ./comptest(_ZN3OMR12CodeGenPhase32performInstructionSelectionPhaseEPN2TR13CodeGeneratorEPNS1_12CodeGenPhaseE+0x12a) [0x2aa323cb76a]
#17: ./comptest(_ZN3OMR12CodeGenPhase10performAllEv+0x1d8) [0x2aa323c9e20]
#18: ./comptest(_ZN3OMR13CodeGenerator12generateCodeEv+0x104) [0x2aa323ba0f4]
#19: ./comptest(_ZN3OMR11Compilation7compileEv+0xe3e) [0x2aa31fceb56]
#20: ./comptest(_Z24compileMethodFromDetailsP12OMR_VMThreadRN2TR24IlGeneratorMethodDetailsE10TR_HotnessRi+0x7da) [0x2aa32000c62]
#21: ./comptest(_ZN4Tril14SimpleCompiler19compileWithVerifierEPN2TR10IlVerifierE+0x400) [0x2aa31f245c8]
#22: ./comptest(_ZN4Tril14SimpleCompiler7compileEv+0x26) [0x2aa31f241ae]
#23: ./comptest(_ZN48Int32SelectInt8CompareTest_UsingConstValues_Test8TestBodyEv+0x51a) [0x2aa31e0d002]
#24: ./comptest(_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x84) [0x2aa31f74d3c]
#25: ./comptest(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x8c) [0x2aa31f6c6ac]
#26: ./comptest(_ZN7testing4Test3RunEv+0x100) [0x2aa31f44e20]
#27: ./comptest(_ZN7testing8TestInfo3RunEv+0x15a) [0x2aa31f45a62]
#28: ./comptest(_ZN7testing8TestCase3RunEv+0x162) [0x2aa31f4645a]
#29: ./comptest(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+0x402) [0x2aa31f50152]

Trace/breakpoint trap (core dumped)

Another assert hit

Address "generateS390CompareOps: Unexpected child type (Int8) with size = 1" assert

This is where it gets complicated. This assert is in the following switch statement:

switch (TR::DataType::getSize(firstChild->getDataType()))
   {
   case 8:
      temp.genericAnalyser (node, isUnsignedCmp ? TR::InstOpCode::CLGR : TR::InstOpCode::CGR,
                           isUnsignedCmp ? TR::InstOpCode::CLG : TR::InstOpCode::CG,
                           TR::InstOpCode::LGR, true, branchTarget, fBranchOpCond, rBranchOpCond);
      returnInstruction = cg->getAppendInstruction();
      isBranchGenerated = true;
      break;
   case 4:
      temp.genericAnalyser (node, isUnsignedCmp ? TR::InstOpCode::CLR : TR::InstOpCode::CR,
                           isUnsignedCmp ? TR::InstOpCode::CL : TR::InstOpCode::C,
                           TR::InstOpCode::LR, true, branchTarget, fBranchOpCond, rBranchOpCond);
      returnInstruction = cg->getAppendInstruction();
      isBranchGenerated = true;
      break;
   case 2:
      temp.genericAnalyser(node, isUnsignedCmp ? TR::InstOpCode::CLR : TR::InstOpCode::CR,
                           isUnsignedCmp ? TR::InstOpCode::CL : TR::InstOpCode::CH,
                           TR::InstOpCode::LR, true, branchTarget, fBranchOpCond, rBranchOpCond);
      returnInstruction = cg->getAppendInstruction();
      isBranchGenerated = true;
      break;
   default:
      TR_ASSERT_FATAL( 0, "generateS390CompareOps: Unexpected child type (%s) with size = %d\n", firstChild->getDataType().toString(), TR::DataType::getSize(firstChild->getDataType()));
      break;
   }

The assert is hit with byte nodes as there is no case 1. Writing a case 1 piece of code here similar to cases 2, 4, and 8 doesn't quite work. For Int64, there is CG for compare, likewise C for Int32 and CH for Int16. However there is no equivalent Z compare opcode for Int8. Working around this would probably involve refactoring TR_S390BinaryCommutativeAnalyser::genericAnalyser, which is a deep rabbit hole.

@joransiu
Copy link
Contributor

Even in case 2, aren't some of the opcodes (CLR, CL, CR) using 32-bit compares? Do we extend the operands to 32-bits?

@Spencer-Comin
Copy link
Contributor

I'm assuming a 16-bit value is extended to 32 bits when it comes into a register, so 32-bit compares between registers should be fine. The CL in case 2 might be problematic though, since it compares against 32 bits in memory when we would want to only compare against 16 bits.

@r30shah
Copy link
Contributor

r30shah commented Feb 22, 2023

@Spencer-Comin , it would be interesting to see how genericAnalyser handles the 16 bit compare as well as 8 bit compare. genericanalyser runs some logic to map those instruction to the one that is compatible with the node. As an experiment, you can quickly check what we generate when you remove that last assert that you hit. Although, we should chase down the path to verify how it will treat both 16 bits and 8 bits values.

@Spencer-Comin
Copy link
Contributor

The only test I'm seeing failing with the assert at [1] is the following https://github.com/eclipse/omr/blob/efe8caf43537270e978f504215342bfba466f0b0/fvtest/compilertriltest/SelectTest.cpp#L1428-L1463
The tree being tested is

(method return=Int32 args=[Int8, Int8]
  (block
    (ireturn
      (iselect
        (bcmpeq
          (bload parm=0)
          (bload parm=1))
        (iconst 1)
        (iconst 0)))))

Which generates the following instructions with the assert removed

    stg   %r15,120(%r15)
    lay   %r15,-160(%r15)
    stg   %r2,176(%r15)
    stg   %r3,184(%r15)
    lhi   %r2,1
    clc   183(1,%r15),191(%r15)
    je    L1
    xr    %r2,%r2
L1:
    lgfr  %r2,%r2
    lg    %r15,280(%r15)
    br    %r14

These instructions seem fine to me

[1] https://github.com/eclipse/omr/blob/efe8caf43537270e978f504215342bfba466f0b0/compiler/z/codegen/OMRTreeEvaluator.cpp#L5233

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants