Unverified Commit 21e1b13f authored by Jay Foad's avatar Jay Foad Committed by GitHub
Browse files

[TwoAddressInstruction] Handle physical registers with LiveIntervals (#66784)

Teach the LiveIntervals path in isPlainlyKilled to handle physical
registers, to get equivalent functionality with the LiveVariables path.

Test this by adding -early-live-intervals RUN lines to a handful of
tests that would fail without this.
parent e4b75d83
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
  bool isCopyToReg(MachineInstr &MI, Register &SrcReg, Register &DstReg,
                   bool &IsSrcPhys, bool &IsDstPhys) const;

  bool isPlainlyKilled(const MachineInstr *MI, LiveRange &LR) const;
  bool isPlainlyKilled(const MachineInstr *MI, Register Reg) const;
  bool isPlainlyKilled(const MachineOperand &MO) const;

@@ -305,27 +306,37 @@ bool TwoAddressInstructionPass::isCopyToReg(MachineInstr &MI, Register &SrcReg,
  return true;
}

bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
                                                LiveRange &LR) const {
  // This is to match the kill flag version where undefs don't have kill flags.
  if (!LR.hasAtLeastOneValue())
    return false;

  SlotIndex useIdx = LIS->getInstructionIndex(*MI);
  LiveInterval::const_iterator I = LR.find(useIdx);
  assert(I != LR.end() && "Reg must be live-in to use.");
  return !I->end.isBlock() && SlotIndex::isSameInstr(I->end, useIdx);
}

/// Test if the given register value, which is used by the
/// given instruction, is killed by the given instruction.
bool TwoAddressInstructionPass::isPlainlyKilled(const MachineInstr *MI,
                                                Register Reg) const {
  if (LIS && Reg.isVirtual() && !LIS->isNotInMIMap(*MI)) {
  // FIXME: Sometimes tryInstructionTransform() will add instructions and
  // test whether they can be folded before keeping them. In this case it
  // sets a kill before recursively calling tryInstructionTransform() again.
  // If there is no interval available, we assume that this instruction is
  // one of those. A kill flag is manually inserted on the operand so the
  // check below will handle it.
    LiveInterval &LI = LIS->getInterval(Reg);
    // This is to match the kill flag version where undefs don't have kill
    // flags.
    if (!LI.hasAtLeastOneValue())
  if (LIS && !LIS->isNotInMIMap(*MI)) {
    if (Reg.isVirtual())
      return isPlainlyKilled(MI, LIS->getInterval(Reg));
    // Reserved registers are considered always live.
    if (MRI->isReserved(Reg))
      return false;

    SlotIndex useIdx = LIS->getInstructionIndex(*MI);
    LiveInterval::const_iterator I = LI.find(useIdx);
    assert(I != LI.end() && "Reg must be live-in to use.");
    return !I->end.isBlock() && SlotIndex::isSameInstr(I->end, useIdx);
    return all_of(TRI->regunits(Reg), [&](MCRegUnit U) {
      return isPlainlyKilled(MI, LIS->getRegUnit(U));
    });
  }

  return MI->killsRegister(Reg);
+8 −0
Original line number Diff line number Diff line
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=ilp32d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=ilp32d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=lp64d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=lp64d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN

declare <vscale x 1 x half> @llvm.maximum.nxv1f16(<vscale x 1 x half>, <vscale x 1 x half>)

+8 −0
Original line number Diff line number Diff line
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFH
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=ilp32d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=ilp32d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=lp64d \
; RUN:   -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfhmin,+v,+m -target-abi=lp64d \
; RUN:   -verify-machineinstrs -early-live-intervals < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN

declare <vscale x 1 x half> @llvm.minimum.nxv1f16(<vscale x 1 x half>, <vscale x 1 x half>)

+4 −0
Original line number Diff line number Diff line
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:     -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
; RUN:     -verify-machineinstrs -early-live-intervals < %s | FileCheck %s
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:     -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
; RUN:     -verify-machineinstrs -early-live-intervals < %s | FileCheck %s

; This tests a mix of vfmsac and vfmsub by using different operand orders to
; trigger commuting in TwoAddressInstructionPass.
+2 −3
Original line number Diff line number Diff line
@@ -249,9 +249,8 @@ define <4 x i32> @test18(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LIS-LABEL: test18:
; CHECK-LIS:       # %bb.0:
; CHECK-LIS-NEXT:    pxor %xmm2, %xmm2
; CHECK-LIS-NEXT:    pxor %xmm3, %xmm3
; CHECK-LIS-NEXT:    pblendw {{.*#+}} xmm3 = xmm0[0,1],xmm3[2,3,4,5,6,7]
; CHECK-LIS-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[1,0,1,1]
; CHECK-LIS-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3,4,5,6,7]
; CHECK-LIS-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,0,1,1]
; CHECK-LIS-NEXT:    pblendw {{.*#+}} xmm2 = xmm1[0,1],xmm2[2,3,4,5,6,7]
; CHECK-LIS-NEXT:    por %xmm0, %xmm2
; CHECK-LIS-NEXT:    movdqa %xmm2, %xmm0
Loading