[all-commits] [llvm/llvm-project] cf0727: [X86] Fix the LEA optimization pass

kazutakahirata via All-commits all-commits at lists.llvm.org
Sun Sep 18 17:50:34 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: cf07277fb47276ba1c3cd661f096098572a6cfb3
      https://github.com/llvm/llvm-project/commit/cf07277fb47276ba1c3cd661f096098572a6cfb3
  Author: Kazu Hirata <kazu at google.com>
  Date:   2022-09-18 (Sun, 18 Sep 2022)

  Changed paths:
    M llvm/lib/Target/X86/X86OptimizeLEAs.cpp
    A llvm/test/CodeGen/X86/pr57673.ll
    A llvm/test/CodeGen/X86/pr57673.mir

  Log Message:
  -----------
  [X86] Fix the LEA optimization pass

The LEA optimization pass visits each basic block of a given machine
function.  In each basic block, for each pair of LEAs that differ only
in their displacement fields, we replace all uses of the second LEA
with the first LEA while adjusting the displacement.

Now, without this patch, after all the replacements are made, the
following assert triggers:

        assert(MRI->use_empty(LastVReg) &&
               "The LEA's def register must have no uses");

The replacement loop uses:

  for (MachineOperand &MO :
       llvm::make_early_inc_range(MRI->use_operands(LastVReg))) {

which is equivalent to:

  for (auto UI = MRI->use_begin(LastVReg), UE = MRI->use_end();
       UI != UE;) {
    MachineOperand &MO = *UI++;  // <-- Look!

That is, immediately after the post increment, make_early_inc_range
already has the iterator for the next iteration in its mind.

The problem is that in one iteration of the loop, we could replace two
uses in a debug instruction like:

  DBG_VALUE_LIST !"r", !DIExpression(DW_OP_LLVM_arg, 0), %0:gr64, %0:gr64, ...

So, the iterator for the next iteration becomes invalid.  We end up
traversing a garbage use list from that point on.  In turn, we don't
get to visit remaining uses.

The patch fixes the problem by switching to a "draining" while loop:

  while (!MRI->use_empty(LastVReg)) {
    MachineOperand &MO = *MRI->use_begin(LastVReg);
    MachineInstr &MI = *MO.getParent();

The credit goes to Simon Pilgrim for reducing the test case.

Fixes https://github.com/llvm/llvm-project/issues/57673

Differential Revision: https://reviews.llvm.org/D133631




More information about the All-commits mailing list