diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 4a7a098efc9ee..30be7024c061d 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -128,8 +128,14 @@ GenTree* Lowering::LowerNode(GenTree* node) break; case GT_ADD: - LowerAdd(node->AsOp()); - break; + { + GenTree* next = LowerAdd(node->AsOp()); + if (next != nullptr) + { + return next; + } + } + break; #if !defined(TARGET_64BIT) case GT_ADD_LO: @@ -4498,12 +4504,43 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable) // Arguments: // node - the node we care about // -void Lowering::LowerAdd(GenTreeOp* node) +// Returns: +// nullptr if no transformation was done, or the next node in the transformed node sequence that +// needs to be lowered. +// +GenTree* Lowering::LowerAdd(GenTreeOp* node) { -#ifndef TARGET_ARMARCH if (varTypeIsIntegralOrI(node->TypeGet())) { + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); LIR::Use use; + + // It is not the best place to do such simple arithmetic optimizations, + // but it allows us to avoid `LEA(addr, 0)` nodes and doing that in morph + // requires more changes. Delete that part if we get an expression optimizer. + if (op2->IsIntegralConst(0)) + { + JITDUMP("Lower: optimize val + 0: "); + DISPNODE(node); + JITDUMP("Replaced with: "); + DISPNODE(op1); + if (BlockRange().TryGetUse(node, &use)) + { + use.ReplaceWith(comp, op1); + } + else + { + op1->SetUnusedValue(); + } + GenTree* next = node->gtNext; + BlockRange().Remove(op2); + BlockRange().Remove(node); + JITDUMP("Remove [06%u], [06%u]\n", op2->gtTreeID, node->gtTreeID); + return next; + } + +#ifndef TARGET_ARMARCH if (BlockRange().TryGetUse(node, &use)) { // If this is a child of an indir, let the parent handle it. @@ -4514,13 +4551,14 @@ void Lowering::LowerAdd(GenTreeOp* node) TryCreateAddrMode(node, false); } } - } #endif // !TARGET_ARMARCH + } if (node->OperIs(GT_ADD)) { ContainCheckBinary(node); } + return nullptr; } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 883a20e16ea7a..f3db1dfd74734 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -278,7 +278,7 @@ class Lowering final : public Phase // Per tree node member functions void LowerStoreIndir(GenTreeIndir* node); - void LowerAdd(GenTreeOp* node); + GenTree* LowerAdd(GenTreeOp* node); bool LowerUnsignedDivOrMod(GenTreeOp* divMod); GenTree* LowerConstIntDivOrMod(GenTree* node); GenTree* LowerSignedDivOrMod(GenTree* node);