From 6f6e722d321714ba1771c62d75f87ba31e67f035 Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 11:29:17 -0400 Subject: [PATCH 1/6] Make simplifyISelectCompare return a boolean Indicates whether a transformation, which always results in turning the op of the compare node into a TR_cmpNE type comparison, occurred or not. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index d9213174f1e..06e14e15448 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -2068,12 +2068,15 @@ static bool processSubTreeLeavesForISelectCompare(TR::NodeChecklist &visited, TR * * \param s * The simplifier object. + * + * \return + * True if a transformation was performed. False otherwise. */ -static void simplifyISelectCompare(TR::Node *compare, TR::Simplifier *s) +static bool simplifyISelectCompare(TR::Node *compare, TR::Simplifier *s) { static char *disableISelectCompareSimplification = feGetEnv("TR_disableISelectCompareSimplification"); if (disableISelectCompareSimplification) - return; + return false; if (compare->getOpCode().isBooleanCompare() && compare->getSecondChild()->getOpCode().isLoadConst() @@ -2095,9 +2098,11 @@ static void simplifyISelectCompare(TR::Node *compare, TR::Simplifier *s) compare->setAndIncChild(1, TR::Node::createConstZeroValue(compare->getSecondChild(), compare->getSecondChild()->getDataType())); constVal->decReferenceCount(); TR::Node::recreate(compare, TR::ILOpCode(TR::ILOpCode::compareOpCode(compare->getFirstChild()->getDataType(), TR_cmpNE, isUnsignedCompare)).convertCmpToIfCmp()); + return true; } } } + return false; } // We handle two kind of cases here: From 17488fa5703ed4c5e3e05069ffd62358bfc621a4 Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 12:20:33 -0400 Subject: [PATCH 2/6] Move body of ificmpneSimplifier to new helper In this commit, the helper is only called from the ificmpneSimplifier itself, so that there is no functional change. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 121 ++++++++++--------- 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index 06e14e15448..ffc8ebd21b9 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -13042,32 +13042,19 @@ TR::Node* removeArithmeticsUnderIntegralCompare(TR::Node* node, return node; } -//--------------------------------------------------------------------- -// Integer if compare equal (signed and unsigned) -// - -TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) +static TR::Node *simplifyIficmpneHelper(TR::Node *node, TR::Block *block, TR::Simplifier *s) { - // Perform a simplification for the case where an iselect is compared to a - // constant. This is done before simplifyChildren because it may allow - // further transformations to be done on the children. - simplifyISelectCompare(node, s); - - s->simplifyChildren(node, block); - if (removeIfToFollowingBlock(node, block, s) == NULL) - return NULL; - - TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild(); + TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild(); if (firstChild == secondChild) { - s->conditionalToUnconditional(node, block, true); + s->conditionalToUnconditional(node, block, false); return node; } makeConstantTheRightChild(node, firstChild, secondChild, s); - if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getInt()==secondChild->getInt()), node, firstChild, secondChild, block, s)) + if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getInt()!=secondChild->getInt()), node, firstChild, secondChild, block, s)) return node; if (conditionalZeroComparisonBranchFold (node, firstChild, secondChild, block, s)) @@ -13075,7 +13062,7 @@ TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier simplifyIntBranchArithmetic(node, firstChild, secondChild, s); - //We will change a if ( a >> C == 0 ) to a if ( a < 2^C ) + //We will change a if ( a >> C != 0 ) to a if ( a >= 2^C ) if ( firstChild->getOpCode().isRightShift() && //First child is a right shift firstChild->getSecondChild()->getOpCode().isLoadConst() && @@ -13084,15 +13071,14 @@ TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier ( firstChild->getOpCodeValue() == TR::iushr || firstChild->getFirstChild()->isNonNegative() - ) && //Either a logical shift or a positive first child to guaruntee zero-extend + ) && //Either a logical shift or a positive first child to guarantee zero-extend secondChild->getOpCode().isLoadConst() && - secondChild->getInt() == 0 && //Second child is a const 0 - performTransformation(s->comp(), "%sTransform (a >> C == 0) to (a < 2^C)\n", s->optDetailString()) + secondChild->getInt() == 0 //Second child is a const 0 ) { //Change if type - TR::Node::recreate(node, TR::ifiucmplt); + TR::Node::recreate(node, TR::ifiucmpge); TR::Node *newSecondChild = TR::Node::create(node, TR::iconst, 0, 1 << firstChild->getSecondChild()->getInt()); node->setAndIncChild(1, newSecondChild); @@ -13117,34 +13103,19 @@ TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier TR::Node::recreate(node, firstChild->getOpCode().convertCmpToIfCmp()); node->setAndIncChild(0, firstChild->getFirstChild()); node->setAndIncChild(1, firstChild->getSecondChild()); - if (secondChild->getInt() == 0) + if (secondChild->getInt() == 1) TR::Node::recreate(node, node->getOpCode().getOpCodeForReverseBranch()); firstChild->recursivelyDecReferenceCount(); secondChild->recursivelyDecReferenceCount(); return node; } - // if we're transforming ificmpeq with an lcmp child if ((firstChild->getOpCodeValue() == TR::lcmp) && ((secondChild->getOpCode().isLoadConst()) && secondChild->getInt() == 0) && performTransformation(s->comp(), "%sChanging if opcode %p because first child %p is an lcmp\n", s->optDetailString(), node, firstChild)) { - TR::Node::recreate(node, TR::iflcmpeq); //change to iflcmp since operands are longs - node->setAndIncChild(0, firstChild->getFirstChild()); - node->setAndIncChild(1, firstChild->getSecondChild()); - firstChild->recursivelyDecReferenceCount(); - secondChild->recursivelyDecReferenceCount(); - return node; - } - - // if we're transforming ificmpeq with an lcmpeq child - if ((firstChild->getOpCodeValue() == TR::lcmpeq) && - ((secondChild->getOpCode().isLoadConst()) && - secondChild->getInt() == 0) && - performTransformation(s->comp(), "%sChanging if opcode %p because first child %p is an lcmpeq\n", s->optDetailString(), node, firstChild)) - { - TR::Node::recreate(node, TR::iflcmpne); //change to iflcmpne since operands are longs + TR::Node::recreate(node, TR::iflcmpne); //change to iflcmp since operands are longs node->setAndIncChild(0, firstChild->getFirstChild()); node->setAndIncChild(1, firstChild->getSecondChild()); firstChild->recursivelyDecReferenceCount(); @@ -13152,27 +13123,24 @@ TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier return node; } - if (node->getOpCodeValue() == TR::ificmpeq) - intCompareNarrower(node, s, TR::ifscmpeq, TR::ifscmpeq, TR::ifbcmpeq); + if (node->getOpCodeValue() == TR::ificmpne) + intCompareNarrower(node, s, TR::ifscmpne, TR::ifscmpne, TR::ifbcmpne); else - unsignedIntCompareNarrower(node, s, TR::ifscmpeq, TR::ifbcmpeq); + unsignedIntCompareNarrower(node, s, TR::ifscmpne, TR::ifbcmpne); addressCompareConversion(node, s); removeArithmeticsUnderIntegralCompare(node, s); partialRedundantCompareElimination(node, block, s); - if (s->getLastRun()) - convertToTestUnderMask(node, block, s); return node; } - //--------------------------------------------------------------------- -// Integer if compare not equal (signed and unsigned) +// Integer if compare equal (signed and unsigned) // -TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) +TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) { // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow @@ -13187,13 +13155,13 @@ TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier if (firstChild == secondChild) { - s->conditionalToUnconditional(node, block, false); + s->conditionalToUnconditional(node, block, true); return node; } makeConstantTheRightChild(node, firstChild, secondChild, s); - if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getInt()!=secondChild->getInt()), node, firstChild, secondChild, block, s)) + if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getInt()==secondChild->getInt()), node, firstChild, secondChild, block, s)) return node; if (conditionalZeroComparisonBranchFold (node, firstChild, secondChild, block, s)) @@ -13201,7 +13169,7 @@ TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier simplifyIntBranchArithmetic(node, firstChild, secondChild, s); - //We will change a if ( a >> C != 0 ) to a if ( a >= 2^C ) + //We will change a if ( a >> C == 0 ) to a if ( a < 2^C ) if ( firstChild->getOpCode().isRightShift() && //First child is a right shift firstChild->getSecondChild()->getOpCode().isLoadConst() && @@ -13210,14 +13178,15 @@ TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier ( firstChild->getOpCodeValue() == TR::iushr || firstChild->getFirstChild()->isNonNegative() - ) && //Either a logical shift or a positive first child to guarantee zero-extend + ) && //Either a logical shift or a positive first child to guaruntee zero-extend secondChild->getOpCode().isLoadConst() && - secondChild->getInt() == 0 //Second child is a const 0 + secondChild->getInt() == 0 && //Second child is a const 0 + performTransformation(s->comp(), "%sTransform (a >> C == 0) to (a < 2^C)\n", s->optDetailString()) ) { //Change if type - TR::Node::recreate(node, TR::ifiucmpge); + TR::Node::recreate(node, TR::ifiucmplt); TR::Node *newSecondChild = TR::Node::create(node, TR::iconst, 0, 1 << firstChild->getSecondChild()->getInt()); node->setAndIncChild(1, newSecondChild); @@ -13242,19 +13211,20 @@ TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier TR::Node::recreate(node, firstChild->getOpCode().convertCmpToIfCmp()); node->setAndIncChild(0, firstChild->getFirstChild()); node->setAndIncChild(1, firstChild->getSecondChild()); - if (secondChild->getInt() == 1) + if (secondChild->getInt() == 0) TR::Node::recreate(node, node->getOpCode().getOpCodeForReverseBranch()); firstChild->recursivelyDecReferenceCount(); secondChild->recursivelyDecReferenceCount(); return node; } + // if we're transforming ificmpeq with an lcmp child if ((firstChild->getOpCodeValue() == TR::lcmp) && ((secondChild->getOpCode().isLoadConst()) && secondChild->getInt() == 0) && performTransformation(s->comp(), "%sChanging if opcode %p because first child %p is an lcmp\n", s->optDetailString(), node, firstChild)) { - TR::Node::recreate(node, TR::iflcmpne); //change to iflcmp since operands are longs + TR::Node::recreate(node, TR::iflcmpeq); //change to iflcmp since operands are longs node->setAndIncChild(0, firstChild->getFirstChild()); node->setAndIncChild(1, firstChild->getSecondChild()); firstChild->recursivelyDecReferenceCount(); @@ -13262,19 +13232,54 @@ TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier return node; } - if (node->getOpCodeValue() == TR::ificmpne) - intCompareNarrower(node, s, TR::ifscmpne, TR::ifscmpne, TR::ifbcmpne); + // if we're transforming ificmpeq with an lcmpeq child + if ((firstChild->getOpCodeValue() == TR::lcmpeq) && + ((secondChild->getOpCode().isLoadConst()) && + secondChild->getInt() == 0) && + performTransformation(s->comp(), "%sChanging if opcode %p because first child %p is an lcmpeq\n", s->optDetailString(), node, firstChild)) + { + TR::Node::recreate(node, TR::iflcmpne); //change to iflcmpne since operands are longs + node->setAndIncChild(0, firstChild->getFirstChild()); + node->setAndIncChild(1, firstChild->getSecondChild()); + firstChild->recursivelyDecReferenceCount(); + secondChild->recursivelyDecReferenceCount(); + return node; + } + + if (node->getOpCodeValue() == TR::ificmpeq) + intCompareNarrower(node, s, TR::ifscmpeq, TR::ifscmpeq, TR::ifbcmpeq); else - unsignedIntCompareNarrower(node, s, TR::ifscmpne, TR::ifbcmpne); + unsignedIntCompareNarrower(node, s, TR::ifscmpeq, TR::ifbcmpeq); addressCompareConversion(node, s); removeArithmeticsUnderIntegralCompare(node, s); partialRedundantCompareElimination(node, block, s); + if (s->getLastRun()) + convertToTestUnderMask(node, block, s); return node; } + +//--------------------------------------------------------------------- +// Integer if compare not equal (signed and unsigned) +// + +TR::Node *ificmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) + { + // Perform a simplification for the case where an iselect is compared to a + // constant. This is done before simplifyChildren because it may allow + // further transformations to be done on the children. + simplifyISelectCompare(node, s); + + s->simplifyChildren(node, block); + if (removeIfToFollowingBlock(node, block, s) == NULL) + return NULL; + + return simplifyIficmpneHelper(node, block, s); + } + //--------------------------------------------------------------------- // Integer if compare less than (signed and unsigned) // From 074dbdee16c3cd5195ef6904c19549ce9f966b58 Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 13:09:06 -0400 Subject: [PATCH 3/6] Call simplifyIficmpneHelper when op has changed to ificmpne Calls the ificmpne simplifier helper when a transformation by simplifyISelectCompare has caused a node's op to change to an ificmpne. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 25 ++++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index ffc8ebd21b9..41980d0d5b0 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -13145,9 +13145,12 @@ TR::Node *ificmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIficmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13289,9 +13292,12 @@ TR::Node *ificmpltSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIficmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13338,9 +13344,12 @@ TR::Node *ificmpleSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIficmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13387,9 +13396,12 @@ TR::Node *ificmpgtSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIficmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13436,9 +13448,12 @@ TR::Node *ificmpgeSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIficmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; From d9b7ee2aafa2f12e7f7c8d8483b32dd82af69b8a Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 13:41:38 -0400 Subject: [PATCH 4/6] Move body of iflcmpneSimplifier to helper and call it Calls simplifyIflcmpneHelper from the iflcmpneSimplifier and when simplifying an iflcmpne op after a transformation from simplifyISelectCompare. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 84 ++++++++++++-------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index 41980d0d5b0..29391d56bf5 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -13494,6 +13494,37 @@ TR::Node *ificmpgeSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier return node; } +TR::Node *simplifyIflcmpneHelper(TR::Node * node, TR::Block * block, TR::Simplifier * s) + { + TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild(); + + if (firstChild == secondChild) + { + s->conditionalToUnconditional(node, block, false); + return node; + } + + makeConstantTheRightChild(node, firstChild, secondChild, s); + + if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getLongInt()!=secondChild->getLongInt()), node, firstChild, secondChild, block, s)) + return node; + + if (conditionalZeroComparisonBranchFold (node, firstChild, secondChild, block, s)) + return node; + + simplifyLongBranchArithmetic(node, firstChild, secondChild, s); + + if (node->getOpCodeValue() == TR::iflcmpne) + { + longCompareNarrower(node, s, TR::ificmpne, TR::ifscmpne, TR::ifscmpne, TR::ifbcmpne); + } + addressCompareConversion(node, s); + removeArithmeticsUnderIntegralCompare(node, s); + + partialRedundantCompareElimination(node, block, s); + return node; + } + //--------------------------------------------------------------------- // Long integer if compare equal (signed and unsigned) // @@ -13503,9 +13534,12 @@ TR::Node *iflcmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIflcmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13553,33 +13587,7 @@ TR::Node *iflcmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; - TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild(); - - if (firstChild == secondChild) - { - s->conditionalToUnconditional(node, block, false); - return node; - } - - makeConstantTheRightChild(node, firstChild, secondChild, s); - - if (firstChild->getOpCode().isLoadConst() && conditionalBranchFold((firstChild->getLongInt()!=secondChild->getLongInt()), node, firstChild, secondChild, block, s)) - return node; - - if (conditionalZeroComparisonBranchFold (node, firstChild, secondChild, block, s)) - return node; - - simplifyLongBranchArithmetic(node, firstChild, secondChild, s); - - if (node->getOpCodeValue() == TR::iflcmpne) - { - longCompareNarrower(node, s, TR::ificmpne, TR::ifscmpne, TR::ifscmpne, TR::ifbcmpne); - } - addressCompareConversion(node, s); - removeArithmeticsUnderIntegralCompare(node, s); - - partialRedundantCompareElimination(node, block, s); - return node; + return simplifyIflcmpneHelper(node, block, s); } //--------------------------------------------------------------------- @@ -13591,9 +13599,12 @@ TR::Node *iflcmpltSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIflcmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13633,9 +13644,12 @@ TR::Node *iflcmpleSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIflcmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13675,9 +13689,12 @@ TR::Node *iflcmpgtSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIflcmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; @@ -13717,9 +13734,12 @@ TR::Node *iflcmpgeSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIflcmpneHelper(node, block, s); + if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; From ec4c97678a25fbe8fe26b25db1c0f3ce789c84f1 Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 13:46:03 -0400 Subject: [PATCH 5/6] Move body of ifacmpneSimplifier to new helper In this commit, the helper is only called from the ifacmpneSimplifier itself, so that there is no functional change. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 45 +++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index 29391d56bf5..ef57346c70e 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -13994,31 +13994,18 @@ TR::Node *normalizeCmpSimplifier(TR::Node * node, TR::Block * block, TR::Simplif return node; } -//--------------------------------------------------------------------- -// Address if compare equal -// - -TR::Node *ifacmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) +static TR::Node *simplifyIfacmpneHelper(TR::Node * node, TR::Block * block, TR::Simplifier * s) { - // Perform a simplification for the case where an iselect is compared to a - // constant. This is done before simplifyChildren because it may allow - // further transformations to be done on the children. - simplifyISelectCompare(node, s); - - if (removeIfToFollowingBlock(node, block, s) == NULL) - return NULL; - s->simplifyChildren(node, block); - TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild(); if (firstChild == secondChild) { - s->conditionalToUnconditional(node, block, true); + s->conditionalToUnconditional(node, block, false); return node; } makeConstantTheRightChild(node, firstChild, secondChild, s); - if (firstChild->getOpCodeValue() == TR::aconst && conditionalBranchFold((firstChild->getAddress()==secondChild->getAddress()), node, firstChild, secondChild, block, s)) + if (firstChild->getOpCodeValue() == TR::aconst && conditionalBranchFold((firstChild->getAddress()!=secondChild->getAddress()), node, firstChild, secondChild, block, s)) return node; // weak symbols aren't necessarily defined, so we have to do the test @@ -14034,9 +14021,10 @@ TR::Node *ifacmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier } //--------------------------------------------------------------------- -// Address if compare not equal +// Address if compare equal // -TR::Node *ifacmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) + +TR::Node *ifacmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) { // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow @@ -14051,12 +14039,12 @@ TR::Node *ifacmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier if (firstChild == secondChild) { - s->conditionalToUnconditional(node, block, false); + s->conditionalToUnconditional(node, block, true); return node; } makeConstantTheRightChild(node, firstChild, secondChild, s); - if (firstChild->getOpCodeValue() == TR::aconst && conditionalBranchFold((firstChild->getAddress()!=secondChild->getAddress()), node, firstChild, secondChild, block, s)) + if (firstChild->getOpCodeValue() == TR::aconst && conditionalBranchFold((firstChild->getAddress()==secondChild->getAddress()), node, firstChild, secondChild, block, s)) return node; // weak symbols aren't necessarily defined, so we have to do the test @@ -14071,6 +14059,23 @@ TR::Node *ifacmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier return node; } +//--------------------------------------------------------------------- +// Address if compare not equal +// +TR::Node *ifacmpneSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier * s) + { + // Perform a simplification for the case where an iselect is compared to a + // constant. This is done before simplifyChildren because it may allow + // further transformations to be done on the children. + simplifyISelectCompare(node, s); + + if (removeIfToFollowingBlock(node, block, s) == NULL) + return NULL; + s->simplifyChildren(node, block); + + return simplifyIfacmpneHelper(node, block, s); + } + //--------------------------------------------------------------------- // If compares that include equality // From 78c12c65c22dfdb4072e00ea7f37e4f44508d6de Mon Sep 17 00:00:00 2001 From: Kevin Dean Date: Thu, 5 Oct 2023 13:49:09 -0400 Subject: [PATCH 6/6] Call simplifyIfacmpneHelper when simplifying an ifacmpne Calls simplifyIfacmpneHelper when simplifyISelectCompare has caused the op to change to an ifacmpne. --- compiler/optimizer/OMRSimplifierHandlers.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/optimizer/OMRSimplifierHandlers.cpp b/compiler/optimizer/OMRSimplifierHandlers.cpp index ef57346c70e..1162040bab9 100644 --- a/compiler/optimizer/OMRSimplifierHandlers.cpp +++ b/compiler/optimizer/OMRSimplifierHandlers.cpp @@ -14029,11 +14029,13 @@ TR::Node *ifacmpeqSimplifier(TR::Node * node, TR::Block * block, TR::Simplifier // Perform a simplification for the case where an iselect is compared to a // constant. This is done before simplifyChildren because it may allow // further transformations to be done on the children. - simplifyISelectCompare(node, s); + bool opChangedToCmpNE = simplifyISelectCompare(node, s); if (removeIfToFollowingBlock(node, block, s) == NULL) return NULL; s->simplifyChildren(node, block); + if (opChangedToCmpNE) + return simplifyIfacmpneHelper(node, block, s); TR::Node * firstChild = node->getFirstChild(), * secondChild = node->getSecondChild();