-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[X86][GISEL] Enable Pre Legalizer Combiner #172204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-llvm-globalisel Author: Mahesh-Attarde (mahesh-attarde) ChangesThis patch enables Pre-legalization Combiner for X86 Target. It includes basic bring up with intent to cover non-regressing support from all_combines. Full diff: https://github.com/llvm/llvm-project/pull/172204.diff 8 Files Affected:
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 434a6d2c3553f..f2880d6c6ea5e 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -19,6 +19,8 @@ tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank)
tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info)
tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1)
+tablegen(LLVM X86GenPreLegalizeGICombiner.inc -gen-global-isel-combiner
+ -combiners="X86PreLegalizerCombiner")
add_public_tablegen_target(X86CommonTableGen)
@@ -87,6 +89,7 @@ set(sources
GISel/X86CallLowering.cpp
GISel/X86InstructionSelector.cpp
GISel/X86LegalizerInfo.cpp
+ GISel/X86PreLegalizerCombiner.cpp
GISel/X86RegisterBankInfo.cpp
)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
new file mode 100644
index 0000000000000..619eda9149baa
--- /dev/null
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -0,0 +1,183 @@
+//===---------------- X86PreLegalizerCombiner.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 pass does combining of machine instructions at the generic MI level,
+/// before the legalizer.
+///
+//===----------------------------------------------------------------------===//
+#include "X86.h"
+#include "X86TargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
+#include "llvm/CodeGen/GlobalISel/Combiner.h"
+#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
+#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
+#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/Instructions.h"
+
+#define GET_GICOMBINER_DEPS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_DEPS
+
+#define DEBUG_TYPE "x86-prelegalizer-combiner"
+
+using namespace llvm;
+using namespace MIPatternMatch;
+
+namespace {
+
+#define GET_GICOMBINER_TYPES
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_TYPES
+
+class X86PreLegalizerCombinerImpl : public Combiner {
+protected:
+ const CombinerHelper Helper;
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig;
+ const X86Subtarget &STI;
+
+public:
+ X86PreLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
+ const X86Subtarget &STI, MachineDominatorTree *MDT,
+ const LegalizerInfo *LI);
+
+ static const char *getName() { return "X86PreLegalizerCombiner"; }
+
+ bool tryCombineAll(MachineInstr &I) const override;
+
+ bool tryCombineAllImpl(MachineInstr &I) const;
+
+private:
+#define GET_GICOMBINER_CLASS_MEMBERS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CLASS_MEMBERS
+};
+
+#define GET_GICOMBINER_IMPL
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_IMPL
+
+X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
+ const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
+ : Combiner(MF, CInfo, TPC, &VT, CSEInfo),
+ Helper(Observer, B, /*IsPreLegalize*/ true, &VT, MDT, LI),
+ RuleConfig(RuleConfig), STI(STI),
+#define GET_GICOMBINER_CONSTRUCTOR_INITS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CONSTRUCTOR_INITS
+{
+}
+
+bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
+ if (tryCombineAllImpl(MI))
+ return true;
+ LLVM_DEBUG(dbgs() << "\nNo table match found.\nTry Custom Combine for "
+ << MI);
+ return false;
+}
+
+class X86PreLegalizerCombiner : public MachineFunctionPass {
+public:
+ static char ID;
+
+ X86PreLegalizerCombiner();
+
+ StringRef getPassName() const override { return "X86PreLegalizerCombiner"; }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ X86PreLegalizerCombinerImplRuleConfig RuleConfig;
+};
+} // end anonymous namespace
+
+void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.setPreservesCFG();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ AU.addRequired<GISelValueTrackingAnalysisLegacy>();
+ AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
+ AU.addRequired<MachineDominatorTreeWrapperPass>();
+ AU.addPreserved<MachineDominatorTreeWrapperPass>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
+ AU.addPreserved<GISelCSEAnalysisWrapperPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+X86PreLegalizerCombiner::X86PreLegalizerCombiner() : MachineFunctionPass(ID) {
+ if (!RuleConfig.parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+}
+
+bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+ if (MF.getProperties().hasFailedISel())
+ return false;
+ auto &TPC = getAnalysis<TargetPassConfig>();
+
+ // Enable CSE.
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
+
+ const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
+ const auto *LI = ST.getLegalizerInfo();
+
+ const Function &F = MF.getFunction();
+ bool EnableOpt =
+ MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
+ GISelValueTracking *VT =
+ &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
+ MachineDominatorTree *MDT =
+ &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+ CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
+ /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
+ F.hasMinSize());
+ // Disable fixed-point iteration to reduce compile-time
+ CInfo.MaxIterations = 1;
+ CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
+ // This is the first Combiner, so the input IR might contain dead
+ // instructions.
+ CInfo.EnableFullDCE = true;
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT, CSEInfo, RuleConfig,
+ ST, MDT, LI);
+ return Impl.combineMachineInstrs();
+}
+
+char X86PreLegalizerCombiner::ID = 0;
+INITIALIZE_PASS_BEGIN(X86PreLegalizerCombiner, DEBUG_TYPE,
+ "Combine X86 machine instrs before legalization", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
+INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
+INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
+ "Combine X86 machine instrs before legalization", false,
+ false)
+
+namespace llvm {
+FunctionPass *createX86PreLegalizerCombiner() {
+ return new X86PreLegalizerCombiner();
+}
+} // end namespace llvm
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 97848bec7127e..d7c4a641c643c 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -220,6 +220,7 @@ InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM,
const X86Subtarget &,
const X86RegisterBankInfo &);
+FunctionPass *createX86PreLegalizerCombiner();
FunctionPass *createX86LoadValueInjectionLoadHardeningPass();
FunctionPass *createX86LoadValueInjectionRetHardeningPass();
FunctionPass *createX86SpeculativeLoadHardeningPass();
@@ -263,6 +264,7 @@ void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
void initializeX86TileConfigPass(PassRegistry &);
void initializeX86SuppressAPXForRelocationPassPass(PassRegistry &);
void initializeX86WinEHUnwindV2Pass(PassRegistry &);
+void initializeX86PreLegalizerCombinerPass(PassRegistry &);
namespace X86AS {
enum : unsigned {
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 8f29a64d58194..c4e63c971bdc8 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -2084,3 +2084,8 @@ def X86 : Target {
//===----------------------------------------------------------------------===//
include "X86PfmCounters.td"
+
+//===----------------------------------------------------------------------===//
+// Global Isel Combiner
+//===----------------------------------------------------------------------===//
+include "X86Combine.td"
diff --git a/llvm/lib/Target/X86/X86Combine.td b/llvm/lib/Target/X86/X86Combine.td
new file mode 100644
index 0000000000000..1c099644a6a0f
--- /dev/null
+++ b/llvm/lib/Target/X86/X86Combine.td
@@ -0,0 +1,20 @@
+//===---------------------- X86Combiner.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
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/GlobalISel/Combine.td"
+
+// all_x86combines is based on generic all_combines, currently x86 gisel does not
+// have vector support and few open issue to address which resulted in failure with
+// combines. We will introduce more combines gradually.
+
+def all_x86combines : GICombineGroup<[identity_combines, reassocs,
+ simplify_add_to_sub]>;
+
+def X86PreLegalizerCombiner : GICombiner<"X86PreLegalizerCombinerImpl", [all_x86combines]> {
+ let CombineAllMethodName = "tryCombineAllImpl";
+}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 713df63479987..8dc558a88a733 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -107,6 +107,7 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86Target() {
initializeX86DynAllocaExpanderLegacyPass(PR);
initializeX86SuppressAPXForRelocationPassPass(PR);
initializeX86WinEHUnwindV2Pass(PR);
+ initializeX86PreLegalizerCombinerPass(PR);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -373,6 +374,7 @@ class X86PassConfig : public TargetPassConfig {
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
+ void addPreLegalizeMachineIR() override;
bool addILPOpts() override;
bool addPreISel() override;
void addMachineSSAOptimization() override;
@@ -487,6 +489,12 @@ bool X86PassConfig::addGlobalInstructionSelect() {
return false;
}
+void X86PassConfig::addPreLegalizeMachineIR() {
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ addPass(createX86PreLegalizerCombiner());
+ }
+}
+
bool X86PassConfig::addILPOpts() {
addPass(&EarlyIfConverterLegacyID);
if (EnableMachineCombinerPass)
diff --git a/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
index e86c04ee22dbd..f55706edf1301 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
@@ -18,10 +18,9 @@ define void @test_scoped_alloca(i64 %n) {
; CHECK-NEXT: .cfi_offset %rbx, -24
; CHECK-NEXT: movq %rsp, %rbx
; CHECK-NEXT: movq %rsp, %rax
-; CHECK-NEXT: imulq $1, %rdi, %rcx
-; CHECK-NEXT: addq $15, %rcx
-; CHECK-NEXT: andq $-16, %rcx
-; CHECK-NEXT: subq %rcx, %rax
+; CHECK-NEXT: addq $15, %rdi
+; CHECK-NEXT: andq $-16, %rdi
+; CHECK-NEXT: subq %rdi, %rax
; CHECK-NEXT: movq %rax, %rsp
; CHECK-NEXT: movq %rax, %rdi
; CHECK-NEXT: callq use_addr
diff --git a/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll b/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
index 1a93e38af9f9b..43ca1b1d0bc48 100644
--- a/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
+++ b/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
@@ -40,12 +40,11 @@ define i32 @baz(i32 %0) {
; CHECK-GISEL: %0:gr32 = COPY $edi
; CHECK-GISEL: %10:gr32 = MOV32ri 1
; CHECK-GISEL: %11:gr32 = MOV32r0 implicit-def dead $eflags
-; CHECK-GISEL: %2:gr32 = SUB32ri %0:gr32(tied-def 0), 0, implicit-def dead $eflags
; CHECK-GISEL: bb.5 (%ir-block.1):
; CHECK-GISEL: ; predecessors: %bb.1
; CHECK-GISEL: successors: %bb.4(0x55555555), %bb.2(0x2aaaaaab); %bb.4(66.67%), %bb.2(33.33%)
; CHECK-GISEL: %3:gr32 = MOV32ri 1
-; CHECK-GISEL: %13:gr8 = COPY %2.sub_8bit:gr32
+; CHECK-GISEL: %13:gr8 = COPY %0.sub_8bit:gr32
; CHECK-GISEL: $cl = COPY %13:gr8
; CHECK-GISEL: %4:gr32 = SHL32rCL %3:gr32(tied-def 0), implicit-def dead $eflags, implicit $cl
; CHECK-GISEL: %6:gr32 = AND32ri %4:gr32(tied-def 0), 13056, implicit-def dead $eflags
|
|
@llvm/pr-subscribers-backend-x86 Author: Mahesh-Attarde (mahesh-attarde) ChangesThis patch enables Pre-legalization Combiner for X86 Target. It includes basic bring up with intent to cover non-regressing support from all_combines. Full diff: https://github.com/llvm/llvm-project/pull/172204.diff 8 Files Affected:
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 434a6d2c3553f..f2880d6c6ea5e 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -19,6 +19,8 @@ tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank)
tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info)
tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1)
+tablegen(LLVM X86GenPreLegalizeGICombiner.inc -gen-global-isel-combiner
+ -combiners="X86PreLegalizerCombiner")
add_public_tablegen_target(X86CommonTableGen)
@@ -87,6 +89,7 @@ set(sources
GISel/X86CallLowering.cpp
GISel/X86InstructionSelector.cpp
GISel/X86LegalizerInfo.cpp
+ GISel/X86PreLegalizerCombiner.cpp
GISel/X86RegisterBankInfo.cpp
)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
new file mode 100644
index 0000000000000..619eda9149baa
--- /dev/null
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -0,0 +1,183 @@
+//===---------------- X86PreLegalizerCombiner.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 pass does combining of machine instructions at the generic MI level,
+/// before the legalizer.
+///
+//===----------------------------------------------------------------------===//
+#include "X86.h"
+#include "X86TargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
+#include "llvm/CodeGen/GlobalISel/Combiner.h"
+#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
+#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
+#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/Instructions.h"
+
+#define GET_GICOMBINER_DEPS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_DEPS
+
+#define DEBUG_TYPE "x86-prelegalizer-combiner"
+
+using namespace llvm;
+using namespace MIPatternMatch;
+
+namespace {
+
+#define GET_GICOMBINER_TYPES
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_TYPES
+
+class X86PreLegalizerCombinerImpl : public Combiner {
+protected:
+ const CombinerHelper Helper;
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig;
+ const X86Subtarget &STI;
+
+public:
+ X86PreLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
+ const X86Subtarget &STI, MachineDominatorTree *MDT,
+ const LegalizerInfo *LI);
+
+ static const char *getName() { return "X86PreLegalizerCombiner"; }
+
+ bool tryCombineAll(MachineInstr &I) const override;
+
+ bool tryCombineAllImpl(MachineInstr &I) const;
+
+private:
+#define GET_GICOMBINER_CLASS_MEMBERS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CLASS_MEMBERS
+};
+
+#define GET_GICOMBINER_IMPL
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_IMPL
+
+X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
+ MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
+ GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
+ const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
+ const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
+ : Combiner(MF, CInfo, TPC, &VT, CSEInfo),
+ Helper(Observer, B, /*IsPreLegalize*/ true, &VT, MDT, LI),
+ RuleConfig(RuleConfig), STI(STI),
+#define GET_GICOMBINER_CONSTRUCTOR_INITS
+#include "X86GenPreLegalizeGICombiner.inc"
+#undef GET_GICOMBINER_CONSTRUCTOR_INITS
+{
+}
+
+bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
+ if (tryCombineAllImpl(MI))
+ return true;
+ LLVM_DEBUG(dbgs() << "\nNo table match found.\nTry Custom Combine for "
+ << MI);
+ return false;
+}
+
+class X86PreLegalizerCombiner : public MachineFunctionPass {
+public:
+ static char ID;
+
+ X86PreLegalizerCombiner();
+
+ StringRef getPassName() const override { return "X86PreLegalizerCombiner"; }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ X86PreLegalizerCombinerImplRuleConfig RuleConfig;
+};
+} // end anonymous namespace
+
+void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetPassConfig>();
+ AU.setPreservesCFG();
+ getSelectionDAGFallbackAnalysisUsage(AU);
+ AU.addRequired<GISelValueTrackingAnalysisLegacy>();
+ AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
+ AU.addRequired<MachineDominatorTreeWrapperPass>();
+ AU.addPreserved<MachineDominatorTreeWrapperPass>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
+ AU.addPreserved<GISelCSEAnalysisWrapperPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+X86PreLegalizerCombiner::X86PreLegalizerCombiner() : MachineFunctionPass(ID) {
+ if (!RuleConfig.parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+}
+
+bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+ if (MF.getProperties().hasFailedISel())
+ return false;
+ auto &TPC = getAnalysis<TargetPassConfig>();
+
+ // Enable CSE.
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
+
+ const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
+ const auto *LI = ST.getLegalizerInfo();
+
+ const Function &F = MF.getFunction();
+ bool EnableOpt =
+ MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
+ GISelValueTracking *VT =
+ &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
+ MachineDominatorTree *MDT =
+ &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
+ CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
+ /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
+ F.hasMinSize());
+ // Disable fixed-point iteration to reduce compile-time
+ CInfo.MaxIterations = 1;
+ CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
+ // This is the first Combiner, so the input IR might contain dead
+ // instructions.
+ CInfo.EnableFullDCE = true;
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT, CSEInfo, RuleConfig,
+ ST, MDT, LI);
+ return Impl.combineMachineInstrs();
+}
+
+char X86PreLegalizerCombiner::ID = 0;
+INITIALIZE_PASS_BEGIN(X86PreLegalizerCombiner, DEBUG_TYPE,
+ "Combine X86 machine instrs before legalization", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
+INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
+INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
+ "Combine X86 machine instrs before legalization", false,
+ false)
+
+namespace llvm {
+FunctionPass *createX86PreLegalizerCombiner() {
+ return new X86PreLegalizerCombiner();
+}
+} // end namespace llvm
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 97848bec7127e..d7c4a641c643c 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -220,6 +220,7 @@ InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM,
const X86Subtarget &,
const X86RegisterBankInfo &);
+FunctionPass *createX86PreLegalizerCombiner();
FunctionPass *createX86LoadValueInjectionLoadHardeningPass();
FunctionPass *createX86LoadValueInjectionRetHardeningPass();
FunctionPass *createX86SpeculativeLoadHardeningPass();
@@ -263,6 +264,7 @@ void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
void initializeX86TileConfigPass(PassRegistry &);
void initializeX86SuppressAPXForRelocationPassPass(PassRegistry &);
void initializeX86WinEHUnwindV2Pass(PassRegistry &);
+void initializeX86PreLegalizerCombinerPass(PassRegistry &);
namespace X86AS {
enum : unsigned {
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 8f29a64d58194..c4e63c971bdc8 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -2084,3 +2084,8 @@ def X86 : Target {
//===----------------------------------------------------------------------===//
include "X86PfmCounters.td"
+
+//===----------------------------------------------------------------------===//
+// Global Isel Combiner
+//===----------------------------------------------------------------------===//
+include "X86Combine.td"
diff --git a/llvm/lib/Target/X86/X86Combine.td b/llvm/lib/Target/X86/X86Combine.td
new file mode 100644
index 0000000000000..1c099644a6a0f
--- /dev/null
+++ b/llvm/lib/Target/X86/X86Combine.td
@@ -0,0 +1,20 @@
+//===---------------------- X86Combiner.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
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/GlobalISel/Combine.td"
+
+// all_x86combines is based on generic all_combines, currently x86 gisel does not
+// have vector support and few open issue to address which resulted in failure with
+// combines. We will introduce more combines gradually.
+
+def all_x86combines : GICombineGroup<[identity_combines, reassocs,
+ simplify_add_to_sub]>;
+
+def X86PreLegalizerCombiner : GICombiner<"X86PreLegalizerCombinerImpl", [all_x86combines]> {
+ let CombineAllMethodName = "tryCombineAllImpl";
+}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 713df63479987..8dc558a88a733 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -107,6 +107,7 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86Target() {
initializeX86DynAllocaExpanderLegacyPass(PR);
initializeX86SuppressAPXForRelocationPassPass(PR);
initializeX86WinEHUnwindV2Pass(PR);
+ initializeX86PreLegalizerCombinerPass(PR);
}
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -373,6 +374,7 @@ class X86PassConfig : public TargetPassConfig {
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
+ void addPreLegalizeMachineIR() override;
bool addILPOpts() override;
bool addPreISel() override;
void addMachineSSAOptimization() override;
@@ -487,6 +489,12 @@ bool X86PassConfig::addGlobalInstructionSelect() {
return false;
}
+void X86PassConfig::addPreLegalizeMachineIR() {
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ addPass(createX86PreLegalizerCombiner());
+ }
+}
+
bool X86PassConfig::addILPOpts() {
addPass(&EarlyIfConverterLegacyID);
if (EnableMachineCombinerPass)
diff --git a/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
index e86c04ee22dbd..f55706edf1301 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/stacksave-stackrestore.ll
@@ -18,10 +18,9 @@ define void @test_scoped_alloca(i64 %n) {
; CHECK-NEXT: .cfi_offset %rbx, -24
; CHECK-NEXT: movq %rsp, %rbx
; CHECK-NEXT: movq %rsp, %rax
-; CHECK-NEXT: imulq $1, %rdi, %rcx
-; CHECK-NEXT: addq $15, %rcx
-; CHECK-NEXT: andq $-16, %rcx
-; CHECK-NEXT: subq %rcx, %rax
+; CHECK-NEXT: addq $15, %rdi
+; CHECK-NEXT: andq $-16, %rdi
+; CHECK-NEXT: subq %rdi, %rax
; CHECK-NEXT: movq %rax, %rsp
; CHECK-NEXT: movq %rax, %rdi
; CHECK-NEXT: callq use_addr
diff --git a/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll b/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
index 1a93e38af9f9b..43ca1b1d0bc48 100644
--- a/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
+++ b/llvm/test/CodeGen/X86/switch-bit-test-unreachable-default.ll
@@ -40,12 +40,11 @@ define i32 @baz(i32 %0) {
; CHECK-GISEL: %0:gr32 = COPY $edi
; CHECK-GISEL: %10:gr32 = MOV32ri 1
; CHECK-GISEL: %11:gr32 = MOV32r0 implicit-def dead $eflags
-; CHECK-GISEL: %2:gr32 = SUB32ri %0:gr32(tied-def 0), 0, implicit-def dead $eflags
; CHECK-GISEL: bb.5 (%ir-block.1):
; CHECK-GISEL: ; predecessors: %bb.1
; CHECK-GISEL: successors: %bb.4(0x55555555), %bb.2(0x2aaaaaab); %bb.4(66.67%), %bb.2(33.33%)
; CHECK-GISEL: %3:gr32 = MOV32ri 1
-; CHECK-GISEL: %13:gr8 = COPY %2.sub_8bit:gr32
+; CHECK-GISEL: %13:gr8 = COPY %0.sub_8bit:gr32
; CHECK-GISEL: $cl = COPY %13:gr8
; CHECK-GISEL: %4:gr32 = SHL32rCL %3:gr32(tied-def 0), implicit-def dead $eflags, implicit $cl
; CHECK-GISEL: %6:gr32 = AND32ri %4:gr32(tied-def 0), 13056, implicit-def dead $eflags
|
This patch enables Pre-legalization Combiner for X86 Target. It includes basic bring up with intent to cover non-regressing support from all_combines.