From c6549d9ef9f37539f8ea4c14073e75c7b69fbd23 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 7 Nov 2022 12:57:30 -0800 Subject: [PATCH] Allow deleting any kind of nodes after address mode formation (#77872) * Allow deleting any kind of nodes after address mode formation This is a general solution to #77152, allowing for deleting any set of nodes that contributed to an address mode, especially those nodes on the `op1` side of a GT_MUL with a zero `op2`. Note that for the #77152 case, this deletes all the `op1` nodes, but leaves behind a dead temp var that was created as part of long MUL rationalization. Fixes #77152. * Add DEBUG_DESTROY_NODE --- src/coreclr/jit/lower.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index d903af6155506..6b1ec741211eb 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -5454,28 +5454,19 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* par { GenTree* unused = unusedStack.Pop(); - // Use a loop to process some of the nodes iteratively - // instead of pushing them on the stack. - while ((unused != base) && (unused != index)) + if ((unused != base) && (unused != index)) { JITDUMP("Removing unused node:\n "); DISPNODE(unused); BlockRange().Remove(unused); - if (unused->OperIs(GT_ADD, GT_MUL, GT_LSH)) + for (GenTree* operand : unused->Operands()) { - // Push the first operand and loop back to process the second one. - // This minimizes the stack depth because the second one tends to be - // a constant so it gets processed and then the first one gets popped. - unusedStack.Push(unused->AsOp()->gtGetOp1()); - unused = unused->AsOp()->gtGetOp2(); - } - else - { - assert(unused->OperIs(GT_CNS_INT)); - break; + unusedStack.Push(operand); } + + DEBUG_DESTROY_NODE(unused); } }