1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/lib/CodeGen/GlobalISel/InstructionSelector.cpp
Gabriel Hjort Åkerlund 0fd4b778e9 [GlobalISel] Add missing operand update when copy is required
When constraining an operand register using constrainOperandRegClass(),
the function may emit a COPY in case the provided register class does
not match the current operand register class. However, the operand
itself is not updated to make use of the COPY, thereby resulting in
incorrect code. This patch fixes that bug by updating the machine
operand accordingly.

Reviewed By: dsanders

Differential Revision: https://reviews.llvm.org/D91244
2021-01-20 10:32:52 +01:00

72 lines
2.4 KiB
C++

//===- llvm/CodeGen/GlobalISel/InstructionSelector.cpp --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This file implements the InstructionSelector class.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#define DEBUG_TYPE "instructionselector"
using namespace llvm;
InstructionSelector::MatcherState::MatcherState(unsigned MaxRenderers)
: Renderers(MaxRenderers), MIs() {}
InstructionSelector::InstructionSelector() = default;
bool InstructionSelector::isOperandImmEqual(
const MachineOperand &MO, int64_t Value,
const MachineRegisterInfo &MRI) const {
if (MO.isReg() && MO.getReg())
if (auto VRegVal = getConstantVRegValWithLookThrough(MO.getReg(), MRI))
return VRegVal->Value.getSExtValue() == Value;
return false;
}
bool InstructionSelector::isBaseWithConstantOffset(
const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
if (!Root.isReg())
return false;
MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)
return false;
MachineOperand &RHS = RootI->getOperand(2);
MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
return false;
return true;
}
bool InstructionSelector::isObviouslySafeToFold(MachineInstr &MI,
MachineInstr &IntoMI) const {
// Immediate neighbours are already folded.
if (MI.getParent() == IntoMI.getParent() &&
std::next(MI.getIterator()) == IntoMI.getIterator())
return true;
return !MI.mayLoadOrStore() && !MI.mayRaiseFPException() &&
!MI.hasUnmodeledSideEffects() && MI.implicit_operands().empty();
}