From a5cbd159a9439fbda9e70f64643deaf8599b7749 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Thu, 6 Oct 2022 20:13:07 -0700 Subject: [PATCH 01/11] Do not set flags for JTRUE op1 --- src/coreclr/jit/lir.cpp | 8 ++++---- src/coreclr/jit/liveness.cpp | 2 +- src/coreclr/jit/lower.cpp | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/lir.cpp b/src/coreclr/jit/lir.cpp index 5adef46eff7930..00fd3ef88e481c 100644 --- a/src/coreclr/jit/lir.cpp +++ b/src/coreclr/jit/lir.cpp @@ -1588,10 +1588,10 @@ bool LIR::Range::CheckLIR(Compiler* compiler, bool checkUnusedValues) const // Stack arguments do not produce a value, but they are considered children of the call. // It may be useful to remove these from being call operands, but that may also impact // other code that relies on being able to reach all the operands from a call node. - // The argument of a JTRUE doesn't produce a value (just sets a flag). - assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK)) || - ((node->OperGet() == GT_JTRUE) && (def->TypeGet() == TYP_VOID) && - ((def->gtFlags & GTF_SET_FLAGS) != 0))); + //// The argument of a JTRUE doesn't produce a value (just sets a flag). + //assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK)) || + // ((node->OperGet() == GT_JTRUE) && (def->TypeGet() == TYP_VOID) && + // ((def->gtFlags & GTF_SET_FLAGS) != 0))); continue; } diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index 8b499069c78f1c..908b270b208af4 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -2136,7 +2136,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR bool Compiler::fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange) { assert(!node->OperIsLocal()); - if (!node->IsValue() || node->IsUnusedValue()) + if ((!node->IsValue() || node->IsUnusedValue()) && !node->OperIsCompare()) { // We are only interested in avoiding the removal of nodes with direct side effects // (as opposed to side effects of their children). diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index a1d649322252be..6dee0988f890ae 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7047,8 +7047,10 @@ void Lowering::ContainCheckJTrue(GenTreeOp* node) { // The compare does not need to be generated into a register. GenTree* cmp = node->gtGetOp1(); + + assert(cmp->OperIsCompare()); + cmp->gtType = TYP_VOID; - cmp->gtFlags |= GTF_SET_FLAGS; } //------------------------------------------------------------------------ From 77cd21b48ab67446df686649193a24024a9abe84 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 7 Oct 2022 11:59:37 -0700 Subject: [PATCH 02/11] Made it passed lsra --- src/coreclr/jit/codegenarmarch.cpp | 1 + src/coreclr/jit/codegenlinear.cpp | 5 +++++ src/coreclr/jit/lir.cpp | 6 ++---- src/coreclr/jit/liveness.cpp | 2 +- src/coreclr/jit/lower.cpp | 3 ++- src/coreclr/jit/lsrabuild.cpp | 4 ++++ src/coreclr/jit/lsraxarch.cpp | 4 ++-- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index b50af8b21477c9..b11311abb29e54 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -359,6 +359,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) #ifdef TARGET_ARM64 case GT_TEST_EQ: case GT_TEST_NE: + assert(!treeNode->isContained()); // On ARM64 genCodeForCompare does not consume its own operands because // genCodeForBinary also has this behavior and it can end up calling // genCodeForCompare when generating compare chains for GT_AND. diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index da8cae58d0c28a..3d85a62aaa7801 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -2623,10 +2623,15 @@ void CodeGen::genCodeForJumpTrue(GenTreeOp* jtrue) { assert(compiler->compCurBB->bbJumpKind == BBJ_COND); assert(jtrue->OperIs(GT_JTRUE)); + assert(jtrue->gtGetOp1()->isContained()); + assert(jtrue->gtGetOp1()->OperIsCompare()); + assert(jtrue->gtGetOp1()->GetRegNum() == REG_NA); GenTreeOp* relop = jtrue->gtGetOp1()->AsOp(); GenCondition condition = GenCondition::FromRelop(relop); + genCodeForCompare(relop); + if (condition.PreferSwap()) { condition = GenCondition::Swap(condition); diff --git a/src/coreclr/jit/lir.cpp b/src/coreclr/jit/lir.cpp index 00fd3ef88e481c..33331c5c7a44c3 100644 --- a/src/coreclr/jit/lir.cpp +++ b/src/coreclr/jit/lir.cpp @@ -1588,10 +1588,8 @@ bool LIR::Range::CheckLIR(Compiler* compiler, bool checkUnusedValues) const // Stack arguments do not produce a value, but they are considered children of the call. // It may be useful to remove these from being call operands, but that may also impact // other code that relies on being able to reach all the operands from a call node. - //// The argument of a JTRUE doesn't produce a value (just sets a flag). - //assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK)) || - // ((node->OperGet() == GT_JTRUE) && (def->TypeGet() == TYP_VOID) && - // ((def->gtFlags & GTF_SET_FLAGS) != 0))); + // The argument of a JTRUE doesn't produce a value (just sets a flag). + assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK))); continue; } diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index 908b270b208af4..8b499069c78f1c 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -2136,7 +2136,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR bool Compiler::fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange) { assert(!node->OperIsLocal()); - if ((!node->IsValue() || node->IsUnusedValue()) && !node->OperIsCompare()) + if (!node->IsValue() || node->IsUnusedValue()) { // We are only interested in avoiding the removal of nodes with direct side effects // (as opposed to side effects of their children). diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 6dee0988f890ae..52e34e2e94d10d 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7050,7 +7050,8 @@ void Lowering::ContainCheckJTrue(GenTreeOp* node) assert(cmp->OperIsCompare()); - cmp->gtType = TYP_VOID; + // cmp->gtType = TYP_VOID; + MakeSrcContained(node, node->gtGetOp1()); } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 370bfc393f23ec..c956a98109321f 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3127,6 +3127,10 @@ int LinearScan::BuildOperandUses(GenTree* node, regMaskTP candidates) { return BuildOperandUses(node->gtGetOp1(), candidates); } + if (node->OperIsCompare()) + { + return BuildBinaryUses(node->AsOp(), candidates); + } #ifdef FEATURE_HW_INTRINSICS if (node->OperIsHWIntrinsic()) { diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 3c5220ba1d9140..2420b5c06d03f4 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -226,10 +226,10 @@ int LinearScan::BuildNode(GenTree* tree) case GT_JTRUE: { - srcCount = 0; assert(dstCount == 0); GenTree* cmp = tree->gtGetOp1(); - assert(!cmp->IsValue()); + srcCount = BuildOperandUses(cmp); + assert(cmp->isContained()); } break; From ff1f83d27be65bd54ff22d9702d4897f35ea0cd5 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 7 Oct 2022 12:17:35 -0700 Subject: [PATCH 03/11] Might work --- src/coreclr/jit/codegencommon.cpp | 2 +- src/coreclr/jit/codegenlinear.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 6e4e7ef0bab69c..83e2eda8cce7fc 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -547,7 +547,7 @@ void CodeGenInterface::genUpdateRegLife(const LclVarDsc* varDsc, bool isBorn, bo // If this is going live, the register must not have a variable in it, except // in the case of an exception or "spill at single-def" variable, which may be already treated // as live in the register. - assert(varDsc->IsAlwaysAliveInMemory() || ((regSet.GetMaskVars() & regMask) == 0)); + //assert(varDsc->IsAlwaysAliveInMemory() || ((regSet.GetMaskVars() & regMask) == 0)); regSet.AddMaskVars(regMask); } } diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 3d85a62aaa7801..0419f2882f4325 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1643,7 +1643,7 @@ void CodeGen::genConsumeRegs(GenTree* tree) unsigned varNum = tree->AsLclVarCommon()->GetLclNum(); LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); - noway_assert(varDsc->GetRegNum() == REG_STK); + // noway_assert(varDsc->GetRegNum() == REG_STK); noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate); // Update the life of the lcl var. From 0767d52009523b8d98b40008c90d0203a880ac99 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 7 Oct 2022 15:42:54 -0700 Subject: [PATCH 04/11] More changes --- src/coreclr/jit/codegencommon.cpp | 2 +- src/coreclr/jit/codegenlinear.cpp | 2 +- src/coreclr/jit/lower.cpp | 5 +++-- src/coreclr/jit/lsrabuild.cpp | 4 ++-- src/coreclr/jit/lsraxarch.cpp | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 83e2eda8cce7fc..6e4e7ef0bab69c 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -547,7 +547,7 @@ void CodeGenInterface::genUpdateRegLife(const LclVarDsc* varDsc, bool isBorn, bo // If this is going live, the register must not have a variable in it, except // in the case of an exception or "spill at single-def" variable, which may be already treated // as live in the register. - //assert(varDsc->IsAlwaysAliveInMemory() || ((regSet.GetMaskVars() & regMask) == 0)); + assert(varDsc->IsAlwaysAliveInMemory() || ((regSet.GetMaskVars() & regMask) == 0)); regSet.AddMaskVars(regMask); } } diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 0419f2882f4325..3d85a62aaa7801 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1643,7 +1643,7 @@ void CodeGen::genConsumeRegs(GenTree* tree) unsigned varNum = tree->AsLclVarCommon()->GetLclNum(); LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); - // noway_assert(varDsc->GetRegNum() == REG_STK); + noway_assert(varDsc->GetRegNum() == REG_STK); noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate); // Update the life of the lcl var. diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 52e34e2e94d10d..dc53aa9d839382 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3222,6 +3222,8 @@ GenTreeCC* Lowering::LowerNodeCC(GenTree* node, GenCondition condition) { if (next->OperIs(GT_JTRUE)) { + assert(!relop->isContained()); + // If the instruction immediately following 'relop', i.e. 'next' is a conditional branch, // it should always have 'relop' as its 'op1'. If it doesn't, then we have improperly // constructed IL (the setting of a condition code should always immediately precede its @@ -7050,8 +7052,7 @@ void Lowering::ContainCheckJTrue(GenTreeOp* node) assert(cmp->OperIsCompare()); - // cmp->gtType = TYP_VOID; - MakeSrcContained(node, node->gtGetOp1()); + MakeSrcContained(node, cmp); } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index c956a98109321f..cd95349b5ea64a 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -4015,7 +4015,7 @@ int LinearScan::BuildCmp(GenTree* tree) #ifdef TARGET_X86 // If the compare is used by a jump, we just need to set the condition codes. If not, then we need // to store the result into the low byte of a register, which requires the dst be a byteable register. - if (tree->TypeGet() != TYP_VOID) + if (tree->TypeGet() != TYP_VOID && !tree->isContained()) { dstCandidates = allByteRegs(); } @@ -4065,7 +4065,7 @@ int LinearScan::BuildCmp(GenTree* tree) int srcCount = BuildOperandUses(op1, op1Candidates); srcCount += BuildOperandUses(op2, op2Candidates); - if (tree->TypeGet() != TYP_VOID) + if (tree->TypeGet() != TYP_VOID && !tree->isContained()) { BuildDef(tree, dstCandidates); } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 2420b5c06d03f4..0b51286f42e280 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -228,7 +228,7 @@ int LinearScan::BuildNode(GenTree* tree) { assert(dstCount == 0); GenTree* cmp = tree->gtGetOp1(); - srcCount = BuildOperandUses(cmp); + srcCount = BuildCmp(cmp); assert(cmp->isContained()); } break; From 20c4465651a7058d71bda3e2b934e512df50a619 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 24 Oct 2022 13:28:52 -0700 Subject: [PATCH 05/11] Trying to simplify --- src/coreclr/jit/lower.cpp | 1 + src/coreclr/jit/lsrabuild.cpp | 4 ++-- src/coreclr/jit/lsraxarch.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 3dc7f6ff604cac..b4e7b632e4557b 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7118,6 +7118,7 @@ void Lowering::ContainCheckJTrue(GenTreeOp* node) GenTree* cmp = node->gtGetOp1(); assert(cmp->OperIsCompare()); + assert(!cmp->gtSetFlags()); MakeSrcContained(node, cmp); } diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 70534a5cfc34e8..0339418280488f 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -4089,7 +4089,7 @@ int LinearScan::BuildCmp(GenTree* tree) #ifdef TARGET_X86 // If the compare is used by a jump, we just need to set the condition codes. If not, then we need // to store the result into the low byte of a register, which requires the dst be a byteable register. - if (tree->TypeGet() != TYP_VOID && !tree->isContained()) + if (tree->TypeGet() != TYP_VOID) { dstCandidates = allByteRegs(); } @@ -4139,7 +4139,7 @@ int LinearScan::BuildCmp(GenTree* tree) int srcCount = BuildOperandUses(op1, op1Candidates); srcCount += BuildOperandUses(op2, op2Candidates); - if (tree->TypeGet() != TYP_VOID && !tree->isContained()) + if (tree->TypeGet() != TYP_VOID) { BuildDef(tree, dstCandidates); } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index baed0f8c54a66a..c82ec421eeeb2b 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -228,8 +228,9 @@ int LinearScan::BuildNode(GenTree* tree) { assert(dstCount == 0); GenTree* cmp = tree->gtGetOp1(); - srcCount = BuildCmp(cmp); assert(cmp->isContained()); + assert(cmp->OperIsCompare()); + srcCount = BuildOperandUses(cmp); } break; From d164b0120163c3332de4e9b33e8c0f08b1713e1b Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 24 Oct 2022 13:47:00 -0700 Subject: [PATCH 06/11] Trying to simplify --- src/coreclr/jit/lsrabuild.cpp | 8 ++------ src/coreclr/jit/lsraxarch.cpp | 4 +++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 0339418280488f..c927b5ddca9615 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3202,10 +3202,6 @@ int LinearScan::BuildOperandUses(GenTree* node, regMaskTP candidates) { return BuildOperandUses(node->gtGetOp1(), candidates); } - if (node->OperIsCompare()) - { - return BuildBinaryUses(node->AsOp(), candidates); - } #ifdef FEATURE_HW_INTRINSICS if (node->OperIsHWIntrinsic()) { @@ -4089,7 +4085,7 @@ int LinearScan::BuildCmp(GenTree* tree) #ifdef TARGET_X86 // If the compare is used by a jump, we just need to set the condition codes. If not, then we need // to store the result into the low byte of a register, which requires the dst be a byteable register. - if (tree->TypeGet() != TYP_VOID) + if (tree->TypeGet() != TYP_VOID && !tree->isContained()) { dstCandidates = allByteRegs(); } @@ -4139,7 +4135,7 @@ int LinearScan::BuildCmp(GenTree* tree) int srcCount = BuildOperandUses(op1, op1Candidates); srcCount += BuildOperandUses(op2, op2Candidates); - if (tree->TypeGet() != TYP_VOID) + if (tree->TypeGet() != TYP_VOID && !tree->isContained()) { BuildDef(tree, dstCandidates); } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index c82ec421eeeb2b..bc2fecdbdbfa06 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -230,7 +230,9 @@ int LinearScan::BuildNode(GenTree* tree) GenTree* cmp = tree->gtGetOp1(); assert(cmp->isContained()); assert(cmp->OperIsCompare()); - srcCount = BuildOperandUses(cmp); + assert(!cmp->gtGetOp1()->OperIs(GT_LCL_VAR_ADDR)); + assert(!cmp->gtGetOp2()->OperIs(GT_LCL_VAR_ADDR)); + srcCount = BuildCmp(cmp); } break; From 91479e8e4a21a504b919c93a198c8896338eb7ec Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 24 Oct 2022 13:53:29 -0700 Subject: [PATCH 07/11] Trying to simplify --- src/coreclr/jit/lsraxarch.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index bc2fecdbdbfa06..8a76c4a738ba85 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -230,8 +230,6 @@ int LinearScan::BuildNode(GenTree* tree) GenTree* cmp = tree->gtGetOp1(); assert(cmp->isContained()); assert(cmp->OperIsCompare()); - assert(!cmp->gtGetOp1()->OperIs(GT_LCL_VAR_ADDR)); - assert(!cmp->gtGetOp2()->OperIs(GT_LCL_VAR_ADDR)); srcCount = BuildCmp(cmp); } break; From 7ba4ff2fffbcb7549da509847eabdf12d500b03b Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 28 Nov 2022 14:41:55 -0800 Subject: [PATCH 08/11] Revert to original assert --- src/coreclr/jit/lir.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lir.cpp b/src/coreclr/jit/lir.cpp index 33331c5c7a44c3..5adef46eff7930 100644 --- a/src/coreclr/jit/lir.cpp +++ b/src/coreclr/jit/lir.cpp @@ -1589,7 +1589,9 @@ bool LIR::Range::CheckLIR(Compiler* compiler, bool checkUnusedValues) const // It may be useful to remove these from being call operands, but that may also impact // other code that relies on being able to reach all the operands from a call node. // The argument of a JTRUE doesn't produce a value (just sets a flag). - assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK))); + assert(((node->OperGet() == GT_CALL) && def->OperIs(GT_PUTARG_STK)) || + ((node->OperGet() == GT_JTRUE) && (def->TypeGet() == TYP_VOID) && + ((def->gtFlags & GTF_SET_FLAGS) != 0))); continue; } From e43c60f0757319e246f992c6282e9906fbc6987f Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 28 Nov 2022 15:13:55 -0800 Subject: [PATCH 09/11] Do not skip compare ops, even if contained --- src/coreclr/jit/codegenlinear.cpp | 2 -- src/coreclr/jit/codegenxarch.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 915f63483e4a4b..ca464fd4bb45c0 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -2621,8 +2621,6 @@ void CodeGen::genCodeForJumpTrue(GenTreeOp* jtrue) GenTreeOp* relop = jtrue->gtGetOp1()->AsOp(); GenCondition condition = GenCondition::FromRelop(relop); - genCodeForCompare(relop); - if (condition.PreferSwap()) { condition = GenCondition::Swap(condition); diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 5849504b0f4029..cecccc47a0aa50 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -1514,7 +1514,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) // contained nodes are part of their parents for codegen purposes // ex : immediates, most LEAs - if (treeNode->isContained()) + if (treeNode->isContained() && !treeNode->OperIsCompare()) { return; } From 530a480cef4f6e271dce231be851d47725f780c0 Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 28 Nov 2022 15:40:51 -0800 Subject: [PATCH 10/11] Unset flags on ContainCheckJTrue --- src/coreclr/jit/lower.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 36ae833e83bdff..a9be15855191be 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -7166,7 +7166,8 @@ void Lowering::ContainCheckJTrue(GenTreeOp* node) GenTree* cmp = node->gtGetOp1(); assert(cmp->OperIsCompare()); - assert(!cmp->gtSetFlags()); + + cmp->gtFlags &= ~GTF_SET_FLAGS; MakeSrcContained(node, cmp); } From 4f1f2ab1805094588d7f8408be95a9226215e84b Mon Sep 17 00:00:00 2001 From: TIHan Date: Mon, 30 Jan 2023 12:03:35 -0800 Subject: [PATCH 11/11] Handling arm --- src/coreclr/jit/lsraarm.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsraarm.cpp b/src/coreclr/jit/lsraarm.cpp index 47cdbaa7539077..09d5bbf46d1a36 100644 --- a/src/coreclr/jit/lsraarm.cpp +++ b/src/coreclr/jit/lsraarm.cpp @@ -310,9 +310,14 @@ int LinearScan::BuildNode(GenTree* tree) break; case GT_JTRUE: - srcCount = 0; + { assert(dstCount == 0); - break; + GenTree* cmp = tree->gtGetOp1(); + assert(cmp->isContained()); + assert(cmp->OperIsCompare()); + srcCount = BuildCmp(cmp); + } + break; case GT_JMP: srcCount = 0;