MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties()
- .set(MachineFunctionProperties::Property::IsSSA);
+ .set(MachineFunctionProperties::Property::IsSSA)
+ .set(MachineFunctionProperties::Property::Legalized);
}
InstructionSelect();
MachineFunctionProperties::Property::IsSSA);
}
+ MachineFunctionProperties getSetProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::Legalized);
+ }
+
bool runOnMachineFunction(MachineFunction &MF) override;
};
} // End namespace llvm.
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties()
- .set(MachineFunctionProperties::Property::IsSSA);
+ .set(MachineFunctionProperties::Property::IsSSA)
+ .set(MachineFunctionProperties::Property::Legalized);
}
/// Walk through \p MF and assign a register bank to every virtual register
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
// other MF/MFI fields we need to initialize.
#ifndef NDEBUG
+ // Check that our input is fully legal: we require the function to have the
+ // Legalized property, so it should be.
+ // FIXME: This should be in the MachineVerifier, but it can't use the
+ // MachineLegalizer as it's currently in the separate GlobalISel library.
+ // The RegBankSelected property is already checked in the verifier. Note
+ // that it has the same layering problem, but we only use inline methods so
+ // end up not needing to link against the GlobalISel library.
+ if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer())
+ for (const MachineBasicBlock &MBB : MF)
+ for (const MachineInstr &MI : MBB)
+ if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI))
+ reportSelectionError(MI, "Instruction is not legal");
+
// FIXME: We could introduce new blocks and will need to fix the outer loop.
// Until then, keep track of the number of blocks to assert that we don't.
const size_t NumBlocks = MF.size();
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
if (F->hasFnAttribute(Attribute::OptimizeNone))
OptMode = Mode::Fast;
init(MF);
+
+#ifndef NDEBUG
+ // Check that our input is fully legal: we require the function to have the
+ // Legalized property, so it should be.
+ // FIXME: This should be in the MachineVerifier, but it can't use the
+ // MachineLegalizer as it's currently in the separate GlobalISel library.
+ if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer()) {
+ for (const MachineBasicBlock &MBB : MF) {
+ for (const MachineInstr &MI : MBB) {
+ if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI)) {
+ std::string ErrStorage;
+ raw_string_ostream Err(ErrStorage);
+ Err << "Instruction is not legal: " << MI << '\n';
+ report_fatal_error(Err.str());
+ }
+ }
+ }
+ }
+#endif
+
// Walk the function and assign register banks to all operands.
// Use a RPOT to make sure all registers are assigned before we choose
// the best mapping of the current instruction.
# CHECK-LABEL: name: add_s32_gpr
name: add_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-LABEL: name: add_s64_gpr
name: add_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-LABEL: name: sub_s32_gpr
name: sub_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-LABEL: name: sub_s64_gpr
name: sub_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-LABEL: name: or_s32_gpr
name: or_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-LABEL: name: or_s64_gpr
name: or_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-LABEL: name: xor_s32_gpr
name: xor_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-LABEL: name: xor_s64_gpr
name: xor_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-LABEL: name: and_s32_gpr
name: and_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# CHECK-LABEL: name: and_s64_gpr
name: and_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-LABEL: name: unconditional_br
name: unconditional_br
isSSA: true
+legalized: true
# CHECK: body:
# CHECK: bb.0:
# CHECK-LABEL: name: load_s64_gpr
name: load_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64sp }
# CHECK-LABEL: name: load_s32_gpr
name: load_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64sp }
# CHECK-LABEL: name: store_s64_gpr
name: store_s64_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64sp }
# CHECK-LABEL: name: store_s32_gpr
name: store_s32_gpr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64sp }
# Based on the type i32, this should be gpr.
name: defaultMapping
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
registers:
# FPR is used for both floating point and vector registers.
name: defaultMappingVector
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: fpr }
registers:
# in FPR, but at the use, it should be GPR.
name: defaultMapping1Repair
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: fpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# Check that we repair the assignment for %0 differently for both uses.
name: defaultMapping2Repairs
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: fpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# fixes that.
name: defaultMappingDefRepair
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
# CHECK-NEXT: - { id: 1, class: fpr }
# Check that we are able to propagate register banks from phis.
name: phiPropagation
isSSA: true
+legalized: true
tracksRegLiveness: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr32 }
# Make sure we can repair physical register uses as well.
name: defaultMappingUseRepairPhysReg
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# Make sure we can repair physical register defs.
name: defaultMappingDefRepairPhysReg
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# G_OR instruction from fpr to gpr.
name: greedyMappingOr
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# %2 constraint.
name: greedyMappingOrWithConstraints
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr }
# CHECK-NEXT: - { id: 1, class: gpr }
# CHECK-LABEL: name: ignoreTargetSpecificInst
name: ignoreTargetSpecificInst
isSSA: true
+legalized: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gpr64 }
# CHECK-NEXT: - { id: 1, class: gpr64 }
--- /dev/null
+# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - | FileCheck %s
+# REQUIRES: global-isel
+
+--- |
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+ define void @legalized_property() { ret void }
+...
+
+---
+# Check that we set the "legalized" property.
+# CHECK-LABEL: name: legalized_property
+# CHECK: legalized: true
+# CHECK: isSSA: true
+name: legalized_property
+isSSA: true
+legalized: false
+body: |
+ bb.0:
+...