diff options
8 files changed, 90 insertions, 2 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h index fcc85b5286a..8828cc80379 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h @@ -32,7 +32,8 @@ public: MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties() - .set(MachineFunctionProperties::Property::IsSSA); + .set(MachineFunctionProperties::Property::IsSSA) + .set(MachineFunctionProperties::Property::Legalized); } InstructionSelect(); diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h index 4bb503a385d..586391341fc 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h @@ -48,6 +48,11 @@ public: MachineFunctionProperties::Property::IsSSA); } + MachineFunctionProperties getSetProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::Legalized); + } + bool runOnMachineFunction(MachineFunction &MF) override; }; } // End namespace llvm. diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h index db8d483ab8c..abaf9cdc904 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -586,7 +586,8 @@ public: 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 diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 3279d13ed76..92a755c9104 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -14,6 +14,7 @@ #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" @@ -51,6 +52,19 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // 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(); diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp index 6248ab46097..bf88d742dba 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -12,6 +12,7 @@ #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" @@ -542,6 +543,26 @@ bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { 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. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir index 8efbaea4ac2..fdb6f6ba273 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir @@ -39,6 +39,7 @@ # CHECK-LABEL: name: add_s32_gpr name: add_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr32 } @@ -63,6 +64,7 @@ body: | # CHECK-LABEL: name: add_s64_gpr name: add_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } @@ -87,6 +89,7 @@ body: | # CHECK-LABEL: name: sub_s32_gpr name: sub_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr32 } @@ -111,6 +114,7 @@ body: | # CHECK-LABEL: name: sub_s64_gpr name: sub_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } @@ -135,6 +139,7 @@ body: | # CHECK-LABEL: name: or_s32_gpr name: or_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr32 } @@ -159,6 +164,7 @@ body: | # CHECK-LABEL: name: or_s64_gpr name: or_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } @@ -183,6 +189,7 @@ body: | # CHECK-LABEL: name: xor_s32_gpr name: xor_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr32 } @@ -207,6 +214,7 @@ body: | # CHECK-LABEL: name: xor_s64_gpr name: xor_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } @@ -231,6 +239,7 @@ body: | # CHECK-LABEL: name: and_s32_gpr name: and_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr32 } @@ -255,6 +264,7 @@ body: | # CHECK-LABEL: name: and_s64_gpr name: and_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } @@ -278,6 +288,7 @@ body: | # CHECK-LABEL: name: unconditional_br name: unconditional_br isSSA: true +legalized: true # CHECK: body: # CHECK: bb.0: @@ -294,6 +305,7 @@ body: | # CHECK-LABEL: name: load_s64_gpr name: load_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64sp } @@ -318,6 +330,7 @@ body: | # CHECK-LABEL: name: load_s32_gpr name: load_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64sp } @@ -342,6 +355,7 @@ body: | # CHECK-LABEL: name: store_s64_gpr name: store_s64_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64sp } @@ -368,6 +382,7 @@ body: | # CHECK-LABEL: name: store_s32_gpr name: store_s32_gpr isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64sp } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir index 76fe671850b..1e04de41c73 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir @@ -63,6 +63,7 @@ # Based on the type i32, this should be gpr. name: defaultMapping isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr } registers: @@ -80,6 +81,7 @@ body: | # 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: @@ -97,6 +99,7 @@ body: | # 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 } @@ -117,6 +120,7 @@ body: | # 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 } @@ -143,6 +147,7 @@ body: | # fixes that. name: defaultMappingDefRepair isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr } # CHECK-NEXT: - { id: 1, class: fpr } @@ -164,6 +169,7 @@ body: | # 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 } @@ -201,6 +207,7 @@ body: | # 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 } @@ -222,6 +229,7 @@ body: | # 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 } @@ -242,6 +250,7 @@ body: | # 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 } @@ -288,6 +297,7 @@ body: | # %2 constraint. name: greedyMappingOrWithConstraints isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr } # CHECK-NEXT: - { id: 1, class: gpr } @@ -334,6 +344,7 @@ body: | # CHECK-LABEL: name: ignoreTargetSpecificInst name: ignoreTargetSpecificInst isSSA: true +legalized: true # CHECK: registers: # CHECK-NEXT: - { id: 0, class: gpr64 } # CHECK-NEXT: - { id: 1, class: gpr64 } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-property.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-property.mir new file mode 100644 index 00000000000..fbac08c0c17 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-property.mir @@ -0,0 +1,20 @@ +# 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: +... |