[llvm] [GISel][X86] port X86PreLegalizerCombiner to npm (PR #182638)
Gergo Stomfai via llvm-commits
llvm-commits at lists.llvm.org
Fri May 1 09:37:02 PDT 2026
https://github.com/stomfaig updated https://github.com/llvm/llvm-project/pull/182638
>From 956adb4a3b823d7a551246866ce2d8ab99b0dbbc Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 00:45:17 +0000
Subject: [PATCH 1/8] port X86PreLegalizerCombiner to npm
---
.../X86/GISel/X86PreLegalizerCombiner.cpp | 38 +++++++++++++++++++
llvm/lib/Target/X86/X86.h | 8 ++++
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 6 +++
llvm/lib/Target/X86/X86PassRegistry.def | 1 +
4 files changed, 53 insertions(+)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 4aa58f0876466..0c70c27fd8a12 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -171,6 +171,44 @@ INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
false)
namespace llvm {
+
+PreservedAnalyses
+X86PreLegalizerCombinerPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ if (MF.getProperties().hasFailedISel())
+ return PreservedAnalyses::all();
+
+ X86PreLegalizerCombinerImplRuleConfig RuleConfig;
+ if (!RuleConfig.parseCommandLineOption())
+ report_fatal_error("Invalid rule identifier");
+
+ auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF);
+
+ const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
+ const LegalizerInfo *LI = ST.getLegalizerInfo();
+
+ const Function &F = MF.getFunction();
+ bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
+ GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
+ MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
+ CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
+ /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
+ F.hasMinSize());
+
+ // This is the first Combiner, so the input IR might contain dead
+ // instructions.
+ CInfo.EnableFullDCE = true;
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, nullptr, VT, CSEInfo.get(),
+ RuleConfig, ST, &MDT, LI);
+ Impl.combineMachineInstrs();
+
+ PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserve<GISelCSEAnalysis>();
+ PA.preserve<GISelValueTrackingAnalysis>();
+ PA.preserve<MachineDominatorTreeAnalysis>();
+ return PA;
+}
+
FunctionPass *createX86PreLegalizerCombiner() {
return new X86PreLegalizerCombiner();
}
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 3b31dee767fae..55a2f84630db5 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -404,6 +404,14 @@ class X86PostLegalizerCombinerPass
};
FunctionPass *createX86PostLegalizerCombinerLegacy();
+
+class X86PreLegalizerCombinerPass
+ : public PassInfoMixin<X86PreLegalizerCombinerPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
FunctionPass *createX86PreLegalizerCombiner();
class X86LoadValueInjectionLoadHardeningPass
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 18901c65f1be0..ffb2c9f52df7e 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -61,6 +61,7 @@ class X86CodeGenPassBuilder
void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
void addAsmPrinter(PassManagerWrapper &PMW) const;
void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+ void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
};
void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
@@ -255,6 +256,11 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
}
}
+void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
+ PassManagerWrapper &PMW) const {
+ addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
+}
+
void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
}
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index 779d1b8eddfd5..c4aafd8dbdb6b 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -59,6 +59,7 @@ MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass())
MACHINE_FUNCTION_PASS("x86-optimize-leas", X86OptimizeLEAsPass())
MACHINE_FUNCTION_PASS("x86-postlegalizer-combiner-pass", X86PostLegalizerCombinerPass())
MACHINE_FUNCTION_PASS("x86-pre-tile-config", X86PreTileConfigPass())
+MACHINE_FUNCTION_PASS("x86-pre-legalizer-combiner-pass", X86PreLegalizerCombinerPass())
MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass())
MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass())
MACHINE_FUNCTION_PASS("x86-slh", X86SpeculativeLoadHardeningPass())
>From 25444bee0091cfdb1c975ed866699416593473cf Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 20:07:57 +0000
Subject: [PATCH 2/8] resolve comments
---
.../X86/GISel/X86PreLegalizerCombiner.cpp | 15 +-
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 12 +-
.../prelegalizercombiner-trivial-arith.mir | 520 ++++++++++++++++++
3 files changed, 533 insertions(+), 14 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 0c70c27fd8a12..22e6815a1d391 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -55,8 +55,7 @@ class X86PreLegalizerCombinerImpl : public Combiner {
MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
GISelCSEInfo *CSEInfo,
const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
- const X86Subtarget &STI, MachineDominatorTree *MDT,
- const LegalizerInfo *LI);
+ MachineDominatorTree *MDT, const LegalizerInfo *LI);
static const char *getName() { return "X86PreLegalizerCombiner"; }
@@ -78,10 +77,10 @@ X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
GISelCSEInfo *CSEInfo,
const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
- const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
+ MachineDominatorTree *MDT, const LegalizerInfo *LI)
: Combiner(MF, CInfo, &VT, CSEInfo),
Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT, LI),
- RuleConfig(RuleConfig), STI(STI),
+ RuleConfig(RuleConfig), STI(MF.getSubtarget<X86Subtarget>()),
#define GET_GICOMBINER_CONSTRUCTOR_INITS
#include "X86GenPreLegalizeGICombiner.inc"
#undef GET_GICOMBINER_CONSTRUCTOR_INITS
@@ -154,7 +153,7 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
// This is the first Combiner, so the input IR might contain dead
// instructions.
CInfo.EnableFullDCE = true;
- X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST, MDT,
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT,
LI);
return Impl.combineMachineInstrs();
}
@@ -198,14 +197,14 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
// This is the first Combiner, so the input IR might contain dead
// instructions.
CInfo.EnableFullDCE = true;
- X86PreLegalizerCombinerImpl Impl(MF, CInfo, nullptr, VT, CSEInfo.get(),
- RuleConfig, ST, &MDT, LI);
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
+ RuleConfig, &MDT, LI);
Impl.combineMachineInstrs();
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserveSet<CFGAnalyses>();
PA.preserve<GISelCSEAnalysis>();
PA.preserve<GISelValueTrackingAnalysis>();
- PA.preserve<MachineDominatorTreeAnalysis>();
return PA;
}
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index ffb2c9f52df7e..6e3846f7d40f9 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -46,6 +46,7 @@ class X86CodeGenPassBuilder
void addIRPasses(PassManagerWrapper &PMW) const;
void addPreISel(PassManagerWrapper &PMW) const;
Error addInstSelector(PassManagerWrapper &PMW) const;
+ void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
void addILPOpts(PassManagerWrapper &PMW) const;
void addPreRegBankSelect(PassManagerWrapper &PMW) const;
void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
@@ -61,7 +62,6 @@ class X86CodeGenPassBuilder
void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
void addAsmPrinter(PassManagerWrapper &PMW) const;
void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
- void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
};
void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
@@ -118,6 +118,11 @@ Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
return Error::success();
}
+void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
+ PassManagerWrapper &PMW) const {
+ addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
+}
+
void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
addMachineFunctionPass(EarlyIfConverterPass(), PMW);
if (X86EnableMachineCombinerPass) {
@@ -256,11 +261,6 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
}
}
-void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
- PassManagerWrapper &PMW) const {
- addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
-}
-
void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
}
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
new file mode 100644
index 0000000000000..c85421a434208
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -0,0 +1,520 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+
+---
+name: right_ident_sub
+tracksRegLiveness: true
+body: |
+ bb.0.entry:
+ liveins: $eax
+ ; Fold (x - 0) -> x
+ ; CHECK-LABEL: name: right_ident_sub
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SUB %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+
+...
+---
+name: right_ident_add
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x + 0) -> x
+ ; CHECK-LABEL: name: right_ident_add
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_ADD %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: mul_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x * 0) -> 0
+ ; CHECK-LABEL: name: mul_0
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $eax = COPY %cst(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_MUL %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: mul_0_cant_replace
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x * 0) -> 0
+ ; CHECK-LABEL: name: mul_0_cant_replace
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %op:gpr(s32) = G_MUL %x, %cst
+ ; CHECK-NEXT: $eax = COPY %op(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:gpr(s32) = G_MUL %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: sdiv_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (0 / x) -> 0
+ ; CHECK-LABEL: name: sdiv_0
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $eax = COPY %cst(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SDIV %cst, %x
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: udiv_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (0 / x) -> 0
+ ; CHECK-LABEL: name: udiv_0
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $eax = COPY %cst(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_UDIV %cst, %x
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: srem_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (0 % x) -> 0
+ ; CHECK-LABEL: name: srem_0
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $eax = COPY %cst(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SREM %cst, %x
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+
+---
+name: urem_0
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (0 % x) -> 0
+ ; CHECK-LABEL: name: urem_0
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $eax = COPY %cst(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_UREM %cst, %x
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: right_ident_or
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x || 0) -> x
+ ; CHECK-LABEL: name: right_ident_or
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_OR %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+
+---
+name: right_ident_xor
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x | 0) -> x
+ ; CHECK-LABEL: name: right_ident_xor
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_XOR %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: right_ident_shl
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x << 0) -> x
+ ; CHECK-LABEL: name: right_ident_shl
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_SHL %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: right_ident_ashr
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x ashr 0) -> x
+ ; CHECK-LABEL: name: right_ident_ashr
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_ASHR %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: right_ident_lshr
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Fold (x lshr 0) -> x
+ ; CHECK-LABEL: name: right_ident_lshr
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %x(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 0
+ %op:_(s32) = G_LSHR %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: dont_fold_sub
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; Not an identity, no folding.
+ ; CHECK-LABEL: name: dont_fold_sub
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+ ; CHECK-NEXT: $eax = COPY %op(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 1
+ %op:_(s32) = G_SUB %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: look_through_zext
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $rax
+ ; CHECK-LABEL: name: look_through_zext
+ ; CHECK: liveins: $rax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %zero:_(s8) = G_CONSTANT i8 0
+ ; CHECK-NEXT: %zext_zero:_(s64) = G_ZEXT %zero(s8)
+ ; CHECK-NEXT: $rax = COPY %zext_zero(s64)
+ ; CHECK-NEXT: RET implicit $rax
+ %zero:_(s8) = G_CONSTANT i8 0
+ %zext_zero:_(s64) = G_ZEXT %zero(s8)
+ %c:_(s64) = G_CONSTANT i64 72340172838076673
+ %mul:_(s64) = G_MUL %c, %zext_zero
+ $rax = COPY %mul(s64)
+ RET implicit $rax
+...
+---
+name: right_ident_ptr_add
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $rax
+ ; Fold (x + 0) -> x
+ ; CHECK-LABEL: name: right_ident_ptr_add
+ ; CHECK: liveins: $rax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(p0) = COPY $rax
+ ; CHECK-NEXT: $rax = COPY %x(p0)
+ ; CHECK-NEXT: RET implicit $rax
+ %x:_(p0) = COPY $rax
+ %cst:_(s64) = G_CONSTANT i64 0
+ %op:_(p0) = G_PTR_ADD %x(p0), %cst
+ $rax = COPY %op(p0)
+ RET implicit $rax
+...
+---
+name: right_identity_rotl
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $eax, $ebx
+ ; CHECK-LABEL: name: right_identity_rotl
+ ; CHECK: liveins: $eax, $ebx
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %copy:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %copy(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %copy:_(s32) = COPY $eax
+ %zero:_(s32) = G_CONSTANT i32 0
+ %rot:_(s32) = G_ROTL %copy(s32), %zero(s32)
+ $eax = COPY %rot(s32)
+ RET implicit $eax
+...
+---
+name: right_identity_rotr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $eax, $ebx
+ ; CHECK-LABEL: name: right_identity_rotr
+ ; CHECK: liveins: $eax, $ebx
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %copy:_(s32) = COPY $eax
+ ; CHECK-NEXT: $eax = COPY %copy(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %copy:_(s32) = COPY $eax
+ %zero:_(s32) = G_CONSTANT i32 0
+ %rot:_(s32) = G_ROTR %copy(s32), %zero(s32)
+ $eax = COPY %rot(s32)
+ RET implicit $eax
+...
+---
+name: lshr_of_vec_zero
+body: |
+ bb.1:
+ liveins: $xmm0
+ ; CHECK-LABEL: name: lshr_of_vec_zero
+ ; CHECK: liveins: $xmm0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $xmm0
+ ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<8 x s16>)
+ ; CHECK-NEXT: RET implicit $xmm0
+ %0:_(<8 x s16>) = COPY $xmm0
+ %5:_(s16) = G_CONSTANT i16 0
+ %zero_vec:_(<8 x s16>) = G_BUILD_VECTOR %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16)
+ %shift:_(<8 x s16>) = G_LSHR %0, %zero_vec(<8 x s16>)
+ $xmm0 = COPY %shift(<8 x s16>)
+ RET implicit $xmm0
+...
+---
+name: ptradd_of_vec_zero
+body: |
+ bb.1:
+ liveins: $xmm0
+ ; CHECK-LABEL: name: ptradd_of_vec_zero
+ ; CHECK: liveins: $xmm0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x p0>) = COPY $xmm0
+ ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<2 x p0>)
+ ; CHECK-NEXT: RET implicit $xmm0
+ %0:_(<2 x p0>) = COPY $xmm0
+ %5:_(s64) = G_CONSTANT i64 0
+ %zero_vec:_(<2 x s64>) = G_BUILD_VECTOR %5(s64), %5(s64)
+ %ptr:_(<2 x p0>) = G_PTR_ADD %0, %zero_vec(<2 x s64>)
+ $xmm0 = COPY %ptr(<2 x p0>)
+ RET implicit $xmm0
+...
+---
+name: i128_or_cst
+liveins:
+ - { reg: '$rax' }
+body: |
+ bb.1:
+ liveins: $rax
+
+ ; CHECK-LABEL: name: i128_or_cst
+ ; CHECK: liveins: $rax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rax
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9223372036854775808
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s128) = G_OR [[LOAD]], [[C]]
+ ; CHECK-NEXT: G_STORE [[OR]](s128), [[COPY]](p0) :: (store (s128), align 4)
+ ; CHECK-NEXT: RET 0
+ %0:_(p0) = COPY $rax
+ %2:_(s128) = G_LOAD %0(p0) :: (load (s128))
+ %4:_(s128) = G_CONSTANT i128 9223372036854775808
+ %5:_(s128) = G_OR %2, %4
+ G_STORE %5(s128), %0(p0) :: (store (s128), align 4)
+ RET 0
+...
+---
+name: mul_1_shift_of_shift
+liveins:
+ - { reg: '$rax' }
+body: |
+ bb.1:
+ liveins: $rax
+
+ ; CHECK-LABEL: name: mul_1_shift_of_shift
+ ; CHECK: liveins: $rax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $rax
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[SHL]], [[C]]
+ ; CHECK-NEXT: $rax = COPY [[OR]](s64)
+ ; CHECK-NEXT: RET implicit $rax
+ %0:_(s64) = COPY $rax
+ %1:_(s64) = G_CONSTANT i64 1
+ %2:_(s64) = G_SHL %0, %1(s64)
+ %3:_(s64) = G_OR %2, %1
+ %4:_(s64) = G_MUL %3, %1
+ $rax = COPY %4(s64)
+ RET implicit $rax
+...
+---
+name: sub_to_add
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; CHECK-LABEL: name: sub_to_add
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+ ; CHECK-NEXT: $eax = COPY %op(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 1
+ %op:_(s32) = G_SUB %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: sub_to_add_nuw
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $eax
+ ; CHECK-LABEL: name: sub_to_add_nuw
+ ; CHECK: liveins: $eax
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:_(s32) = COPY $eax
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
+ ; CHECK-NEXT: $eax = COPY %op(s32)
+ ; CHECK-NEXT: RET implicit $eax
+ %x:_(s32) = COPY $eax
+ %cst:_(s32) = G_CONSTANT i32 1
+ %op:_(s32) = nuw G_SUB %x(s32), %cst
+ $eax = COPY %op(s32)
+ RET implicit $eax
+...
+---
+name: sub_to_add_nsw_128
+body: |
+ bb.0:
+ liveins: $eax, $ebx
+
+ ; CHECK-LABEL: name: sub_to_add_nsw_128
+ ; CHECK: liveins: $eax, $ebx
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(s32) = COPY $eax
+ ; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32)
+ ; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128
+ ; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c
+ ; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8)
+ ; CHECK-NEXT: $eax = COPY %d(s32)
+ ; CHECK-NEXT: RET implicit $rax
+ %a:_(s32) = COPY $eax
+ %b:_(s8) = G_TRUNC %a
+ %c:_(s8) = G_CONSTANT i8 -128
+ %add:_(s8) = nsw nuw G_SUB %b, %c
+ %d:_(s32) = G_ZEXT %add
+ $eax = COPY %d
+ RET implicit $rax
+...
+---
+name: sub_to_add_nsw_intmin
+body: |
+ bb.0:
+ liveins: $eax, $ebx
+
+ ; CHECK-LABEL: name: sub_to_add_nsw_intmin
+ ; CHECK: liveins: $eax, $ebx
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %a:_(s32) = COPY $eax
+ ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648
+ ; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c
+ ; CHECK-NEXT: $eax = COPY %add(s32)
+ ; CHECK-NEXT: RET implicit $rax
+ %a:_(s32) = COPY $eax
+ %c:_(s32) = G_CONSTANT i32 -2147483648
+ %add:_(s32) = nsw nuw G_SUB %a, %c
+ $eax = COPY %add
+ RET implicit $rax
+...
>From e2af25d4197f38ddbaeeb27bafc851d0e06d4881 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sat, 21 Feb 2026 20:35:04 +0000
Subject: [PATCH 3/8] remove LI duplicated dependence
---
.../lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 22e6815a1d391..abe20a74b273c 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -55,7 +55,7 @@ class X86PreLegalizerCombinerImpl : public Combiner {
MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
GISelCSEInfo *CSEInfo,
const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
- MachineDominatorTree *MDT, const LegalizerInfo *LI);
+ MachineDominatorTree *MDT);
static const char *getName() { return "X86PreLegalizerCombiner"; }
@@ -77,9 +77,10 @@ X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
GISelCSEInfo *CSEInfo,
const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
- MachineDominatorTree *MDT, const LegalizerInfo *LI)
+ MachineDominatorTree *MDT)
: Combiner(MF, CInfo, &VT, CSEInfo),
- Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT, LI),
+ Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT,
+ MF.getSubtarget<X86Subtarget>().getLegalizerInfo()),
RuleConfig(RuleConfig), STI(MF.getSubtarget<X86Subtarget>()),
#define GET_GICOMBINER_CONSTRUCTOR_INITS
#include "X86GenPreLegalizeGICombiner.inc"
@@ -153,8 +154,7 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
// This is the first Combiner, so the input IR might contain dead
// instructions.
CInfo.EnableFullDCE = true;
- X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT,
- LI);
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
return Impl.combineMachineInstrs();
}
@@ -198,7 +198,7 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
// instructions.
CInfo.EnableFullDCE = true;
X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
- RuleConfig, &MDT, LI);
+ RuleConfig, &MDT);
Impl.combineMachineInstrs();
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
>From b156578848de85a0ff03ef3333d7b0ad00b2536f Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Sun, 22 Feb 2026 09:27:05 +0000
Subject: [PATCH 4/8] include npm tests
---
llvm/lib/Target/X86/X86PassRegistry.def | 2 +-
.../X86/GlobalISel/prelegalizercombiner-trivial-arith.mir | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index c4aafd8dbdb6b..45e7d0ebdbf7b 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -59,7 +59,7 @@ MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass())
MACHINE_FUNCTION_PASS("x86-optimize-leas", X86OptimizeLEAsPass())
MACHINE_FUNCTION_PASS("x86-postlegalizer-combiner-pass", X86PostLegalizerCombinerPass())
MACHINE_FUNCTION_PASS("x86-pre-tile-config", X86PreTileConfigPass())
-MACHINE_FUNCTION_PASS("x86-pre-legalizer-combiner-pass", X86PreLegalizerCombinerPass())
+MACHINE_FUNCTION_PASS("x86-prelegalizer-combiner-pass", X86PreLegalizerCombinerPass())
MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass())
MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass())
MACHINE_FUNCTION_PASS("x86-slh", X86SpeculativeLoadHardeningPass())
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
index c85421a434208..cce4f248aa199 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: right_ident_sub
>From ac93919ba507dcafae22c1e9d5d094be155f5c54 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Tue, 24 Feb 2026 17:37:57 +0000
Subject: [PATCH 5/8] add Legacy to lpm pass
---
.../X86/GISel/X86PreLegalizerCombiner.cpp | 25 +++++++++++--------
llvm/lib/Target/X86/X86.h | 4 +--
llvm/lib/Target/X86/X86TargetMachine.cpp | 4 +--
3 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index abe20a74b273c..43f0b87d9329b 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -92,13 +92,15 @@ bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
return tryCombineAllImpl(MI);
}
-class X86PreLegalizerCombiner : public MachineFunctionPass {
+class X86PreLegalizerCombinerLegacy : public MachineFunctionPass {
public:
static char ID;
- X86PreLegalizerCombiner();
+ X86PreLegalizerCombinerLegacy();
- StringRef getPassName() const override { return "X86PreLegalizerCombiner"; }
+ StringRef getPassName() const override {
+ return "X86PreLegalizerCombinerLegacy";
+ }
bool runOnMachineFunction(MachineFunction &MF) override;
@@ -109,7 +111,7 @@ class X86PreLegalizerCombiner : public MachineFunctionPass {
};
} // end anonymous namespace
-void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void X86PreLegalizerCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
@@ -122,12 +124,13 @@ void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
-X86PreLegalizerCombiner::X86PreLegalizerCombiner() : MachineFunctionPass(ID) {
+X86PreLegalizerCombinerLegacy::X86PreLegalizerCombinerLegacy()
+ : MachineFunctionPass(ID) {
if (!RuleConfig.parseCommandLineOption())
report_fatal_error("Invalid rule identifier");
}
-bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
auto &TPC = getAnalysis<TargetPassConfig>();
@@ -158,14 +161,14 @@ bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
return Impl.combineMachineInstrs();
}
-char X86PreLegalizerCombiner::ID = 0;
-INITIALIZE_PASS_BEGIN(X86PreLegalizerCombiner, DEBUG_TYPE,
+char X86PreLegalizerCombinerLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(X86PreLegalizerCombinerLegacy, 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,
+INITIALIZE_PASS_END(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
"Combine X86 machine instrs before legalization", false,
false)
@@ -208,7 +211,7 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
return PA;
}
-FunctionPass *createX86PreLegalizerCombiner() {
- return new X86PreLegalizerCombiner();
+FunctionPass *createX86PreLegalizerCombinerLegacy() {
+ return new X86PreLegalizerCombinerLegacy();
}
} // end namespace llvm
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 55a2f84630db5..a934abb78e956 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -412,7 +412,7 @@ class X86PreLegalizerCombinerPass
MachineFunctionAnalysisManager &MFAM);
};
-FunctionPass *createX86PreLegalizerCombiner();
+FunctionPass *createX86PreLegalizerCombinerLegacy();
class X86LoadValueInjectionLoadHardeningPass
: public PassInfoMixin<X86LoadValueInjectionLoadHardeningPass> {
@@ -497,7 +497,7 @@ void initializeX86SpeculativeLoadHardeningLegacyPass(PassRegistry &);
void initializeX86SuppressAPXForRelocationLegacyPass(PassRegistry &);
void initializeX86TileConfigLegacyPass(PassRegistry &);
void initializeX86WinEHUnwindV2LegacyPass(PassRegistry &);
-void initializeX86PreLegalizerCombinerPass(PassRegistry &);
+void initializeX86PreLegalizerCombinerLegacyPass(PassRegistry &);
void initializeX86PostLegalizerCombinerLegacyPass(PassRegistry &);
namespace X86AS {
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 6de566b39d045..5c8a508f37917 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -107,7 +107,7 @@ extern "C" LLVM_C_ABI void LLVMInitializeX86Target() {
initializeX86DynAllocaExpanderLegacyPass(PR);
initializeX86SuppressAPXForRelocationLegacyPass(PR);
initializeX86WinEHUnwindV2LegacyPass(PR);
- initializeX86PreLegalizerCombinerPass(PR);
+ initializeX86PreLegalizerCombinerLegacyPass(PR);
initializeX86PostLegalizerCombinerLegacyPass(PR);
}
@@ -495,7 +495,7 @@ bool X86PassConfig::addGlobalInstructionSelect() {
void X86PassConfig::addPreLegalizeMachineIR() {
if (getOptLevel() != CodeGenOptLevel::None) {
- addPass(createX86PreLegalizerCombiner());
+ addPass(createX86PreLegalizerCombinerLegacy());
}
}
>From 8be6041bda9e2ef87537e012080c1942f2fe2379 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Tue, 24 Feb 2026 20:02:34 +0000
Subject: [PATCH 6/8] create CombinerInfo factory fn
---
.../X86/GISel/X86PreLegalizerCombiner.cpp | 35 +++++++------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 43f0b87d9329b..99ed6de00183a 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/IR/Instructions.h"
#define GET_GICOMBINER_DEPS
@@ -40,6 +41,16 @@ using namespace MIPatternMatch;
namespace {
+CombinerInfo createCombinerInfo(bool EnableOpt, const Function &F) {
+ CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
+ nullptr, EnableOpt, F.hasOptSize(), F.hasMinSize());
+
+ // This is the first Combiner, so the input IR might contain dead
+ // instructions.
+ CInfo.EnableFullDCE = true;
+ return CInfo;
+}
+
#define GET_GICOMBINER_TYPES
#include "X86GenPreLegalizeGICombiner.inc"
#undef GET_GICOMBINER_TYPES
@@ -139,10 +150,6 @@ bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
GISelCSEAnalysisWrapper &Wrapper =
getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
-
- const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
- const LegalizerInfo *LI = ST.getLegalizerInfo();
-
const Function &F = MF.getFunction();
bool EnableOpt =
MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
@@ -150,13 +157,7 @@ bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
&getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
MachineDominatorTree *MDT =
&getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
- CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
- /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
- F.hasMinSize());
-
- // This is the first Combiner, so the input IR might contain dead
- // instructions.
- CInfo.EnableFullDCE = true;
+ CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
return Impl.combineMachineInstrs();
}
@@ -185,21 +186,11 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
report_fatal_error("Invalid rule identifier");
auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(MF);
-
- const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
- const LegalizerInfo *LI = ST.getLegalizerInfo();
-
const Function &F = MF.getFunction();
bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
- CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
- /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
- F.hasMinSize());
-
- // This is the first Combiner, so the input IR might contain dead
- // instructions.
- CInfo.EnableFullDCE = true;
+ CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
RuleConfig, &MDT);
Impl.combineMachineInstrs();
>From bdfe5e2fcc7dc293f85566a25273601c07257aae Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Fri, 1 May 2026 16:00:38 +0100
Subject: [PATCH 7/8] hook up tests
---
.../X86/GISel/X86PreLegalizerCombiner.cpp | 1 -
.../GlobalISel/prelegalizer-combiner-div.mir | 1 +
.../prelegalizer-combiner-identity.mir | 1 +
.../GlobalISel/prelegalizer-combiner-lshr.mir | 1 +
.../GlobalISel/prelegalizer-combiner-mul.mir | 1 +
.../GlobalISel/prelegalizer-combiner-or.mir | 1 +
.../prelegalizer-combiner-ptr-add.mir | 1 +
.../GlobalISel/prelegalizer-combiner-rem.mir | 1 +
.../GlobalISel/prelegalizer-combiner-sub.mir | 1 +
.../prelegalizercombiner-trivial-arith.mir | 521 ------------------
10 files changed, 8 insertions(+), 522 deletions(-)
delete mode 100644 llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 99ed6de00183a..18333944ce52b 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -27,7 +27,6 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/IR/Instructions.h"
#define GET_GICOMBINER_DEPS
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
index 717f0daaddcd6..dc9c458cf2b02 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-div.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: sdiv_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
index ebc9d92301c57..d41198950fc10 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-identity.mir
@@ -1,4 +1,5 @@
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: right_ident_sub
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
index 4db7750258801..2ded48ba58d01 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-lshr.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: lshr_of_vec_zero
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
index fce8b011a31eb..ed13149ea086a 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-mul.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: mul_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
index 9b34333dd3c22..29433a21cbff3 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-or.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: i128_or_cst
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
index 4c3c5d2e1e7fd..2a8612ce3ee5b 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-ptr-add.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: ptradd_of_vec_zero
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
index 500223080f899..2b98c5792e07b 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-rem.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: srem_0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
index 05215130a30f2..26965e3ecad73 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/prelegalizer-combiner-sub.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
+# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
---
name: dont_fold_sub
diff --git a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
deleted file mode 100644
index cce4f248aa199..0000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/prelegalizercombiner-trivial-arith.mir
+++ /dev/null
@@ -1,521 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple x86_64 -run-pass=x86-prelegalizer-combiner %s -o - | FileCheck %s
-# RUN: llc -mtriple x86_64 -passes=x86-prelegalizer-combiner-pass %s -o - | FileCheck %s
-
----
-name: right_ident_sub
-tracksRegLiveness: true
-body: |
- bb.0.entry:
- liveins: $eax
- ; Fold (x - 0) -> x
- ; CHECK-LABEL: name: right_ident_sub
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_SUB %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-
-...
----
-name: right_ident_add
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x + 0) -> x
- ; CHECK-LABEL: name: right_ident_add
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_ADD %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: mul_0
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x * 0) -> 0
- ; CHECK-LABEL: name: mul_0
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $eax = COPY %cst(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_MUL %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: mul_0_cant_replace
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x * 0) -> 0
- ; CHECK-LABEL: name: mul_0_cant_replace
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: %op:gpr(s32) = G_MUL %x, %cst
- ; CHECK-NEXT: $eax = COPY %op(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:gpr(s32) = G_MUL %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: sdiv_0
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (0 / x) -> 0
- ; CHECK-LABEL: name: sdiv_0
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $eax = COPY %cst(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_SDIV %cst, %x
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: udiv_0
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (0 / x) -> 0
- ; CHECK-LABEL: name: udiv_0
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $eax = COPY %cst(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_UDIV %cst, %x
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: srem_0
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (0 % x) -> 0
- ; CHECK-LABEL: name: srem_0
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $eax = COPY %cst(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_SREM %cst, %x
- $eax = COPY %op(s32)
- RET implicit $eax
-...
-
----
-name: urem_0
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (0 % x) -> 0
- ; CHECK-LABEL: name: urem_0
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $eax = COPY %cst(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_UREM %cst, %x
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: right_ident_or
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x || 0) -> x
- ; CHECK-LABEL: name: right_ident_or
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_OR %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
-
----
-name: right_ident_xor
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x | 0) -> x
- ; CHECK-LABEL: name: right_ident_xor
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_XOR %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: right_ident_shl
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x << 0) -> x
- ; CHECK-LABEL: name: right_ident_shl
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_SHL %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: right_ident_ashr
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x ashr 0) -> x
- ; CHECK-LABEL: name: right_ident_ashr
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_ASHR %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: right_ident_lshr
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Fold (x lshr 0) -> x
- ; CHECK-LABEL: name: right_ident_lshr
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %x(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 0
- %op:_(s32) = G_LSHR %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: dont_fold_sub
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; Not an identity, no folding.
- ; CHECK-LABEL: name: dont_fold_sub
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
- ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
- ; CHECK-NEXT: $eax = COPY %op(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 1
- %op:_(s32) = G_SUB %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: look_through_zext
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $rax
- ; CHECK-LABEL: name: look_through_zext
- ; CHECK: liveins: $rax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %zero:_(s8) = G_CONSTANT i8 0
- ; CHECK-NEXT: %zext_zero:_(s64) = G_ZEXT %zero(s8)
- ; CHECK-NEXT: $rax = COPY %zext_zero(s64)
- ; CHECK-NEXT: RET implicit $rax
- %zero:_(s8) = G_CONSTANT i8 0
- %zext_zero:_(s64) = G_ZEXT %zero(s8)
- %c:_(s64) = G_CONSTANT i64 72340172838076673
- %mul:_(s64) = G_MUL %c, %zext_zero
- $rax = COPY %mul(s64)
- RET implicit $rax
-...
----
-name: right_ident_ptr_add
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $rax
- ; Fold (x + 0) -> x
- ; CHECK-LABEL: name: right_ident_ptr_add
- ; CHECK: liveins: $rax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(p0) = COPY $rax
- ; CHECK-NEXT: $rax = COPY %x(p0)
- ; CHECK-NEXT: RET implicit $rax
- %x:_(p0) = COPY $rax
- %cst:_(s64) = G_CONSTANT i64 0
- %op:_(p0) = G_PTR_ADD %x(p0), %cst
- $rax = COPY %op(p0)
- RET implicit $rax
-...
----
-name: right_identity_rotl
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $eax, $ebx
- ; CHECK-LABEL: name: right_identity_rotl
- ; CHECK: liveins: $eax, $ebx
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %copy:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %copy(s32)
- ; CHECK-NEXT: RET implicit $eax
- %copy:_(s32) = COPY $eax
- %zero:_(s32) = G_CONSTANT i32 0
- %rot:_(s32) = G_ROTL %copy(s32), %zero(s32)
- $eax = COPY %rot(s32)
- RET implicit $eax
-...
----
-name: right_identity_rotr
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $eax, $ebx
- ; CHECK-LABEL: name: right_identity_rotr
- ; CHECK: liveins: $eax, $ebx
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %copy:_(s32) = COPY $eax
- ; CHECK-NEXT: $eax = COPY %copy(s32)
- ; CHECK-NEXT: RET implicit $eax
- %copy:_(s32) = COPY $eax
- %zero:_(s32) = G_CONSTANT i32 0
- %rot:_(s32) = G_ROTR %copy(s32), %zero(s32)
- $eax = COPY %rot(s32)
- RET implicit $eax
-...
----
-name: lshr_of_vec_zero
-body: |
- bb.1:
- liveins: $xmm0
- ; CHECK-LABEL: name: lshr_of_vec_zero
- ; CHECK: liveins: $xmm0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $xmm0
- ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<8 x s16>)
- ; CHECK-NEXT: RET implicit $xmm0
- %0:_(<8 x s16>) = COPY $xmm0
- %5:_(s16) = G_CONSTANT i16 0
- %zero_vec:_(<8 x s16>) = G_BUILD_VECTOR %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16), %5(s16)
- %shift:_(<8 x s16>) = G_LSHR %0, %zero_vec(<8 x s16>)
- $xmm0 = COPY %shift(<8 x s16>)
- RET implicit $xmm0
-...
----
-name: ptradd_of_vec_zero
-body: |
- bb.1:
- liveins: $xmm0
- ; CHECK-LABEL: name: ptradd_of_vec_zero
- ; CHECK: liveins: $xmm0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x p0>) = COPY $xmm0
- ; CHECK-NEXT: $xmm0 = COPY [[COPY]](<2 x p0>)
- ; CHECK-NEXT: RET implicit $xmm0
- %0:_(<2 x p0>) = COPY $xmm0
- %5:_(s64) = G_CONSTANT i64 0
- %zero_vec:_(<2 x s64>) = G_BUILD_VECTOR %5(s64), %5(s64)
- %ptr:_(<2 x p0>) = G_PTR_ADD %0, %zero_vec(<2 x s64>)
- $xmm0 = COPY %ptr(<2 x p0>)
- RET implicit $xmm0
-...
----
-name: i128_or_cst
-liveins:
- - { reg: '$rax' }
-body: |
- bb.1:
- liveins: $rax
-
- ; CHECK-LABEL: name: i128_or_cst
- ; CHECK: liveins: $rax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rax
- ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128))
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9223372036854775808
- ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s128) = G_OR [[LOAD]], [[C]]
- ; CHECK-NEXT: G_STORE [[OR]](s128), [[COPY]](p0) :: (store (s128), align 4)
- ; CHECK-NEXT: RET 0
- %0:_(p0) = COPY $rax
- %2:_(s128) = G_LOAD %0(p0) :: (load (s128))
- %4:_(s128) = G_CONSTANT i128 9223372036854775808
- %5:_(s128) = G_OR %2, %4
- G_STORE %5(s128), %0(p0) :: (store (s128), align 4)
- RET 0
-...
----
-name: mul_1_shift_of_shift
-liveins:
- - { reg: '$rax' }
-body: |
- bb.1:
- liveins: $rax
-
- ; CHECK-LABEL: name: mul_1_shift_of_shift
- ; CHECK: liveins: $rax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $rax
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[COPY]], [[C]](s64)
- ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s64) = G_OR [[SHL]], [[C]]
- ; CHECK-NEXT: $rax = COPY [[OR]](s64)
- ; CHECK-NEXT: RET implicit $rax
- %0:_(s64) = COPY $rax
- %1:_(s64) = G_CONSTANT i64 1
- %2:_(s64) = G_SHL %0, %1(s64)
- %3:_(s64) = G_OR %2, %1
- %4:_(s64) = G_MUL %3, %1
- $rax = COPY %4(s64)
- RET implicit $rax
-...
----
-name: sub_to_add
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; CHECK-LABEL: name: sub_to_add
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
- ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
- ; CHECK-NEXT: $eax = COPY %op(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 1
- %op:_(s32) = G_SUB %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: sub_to_add_nuw
-tracksRegLiveness: true
-body: |
- bb.1.entry:
- liveins: $eax
- ; CHECK-LABEL: name: sub_to_add_nuw
- ; CHECK: liveins: $eax
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %x:_(s32) = COPY $eax
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
- ; CHECK-NEXT: %op:_(s32) = G_ADD %x, [[C]]
- ; CHECK-NEXT: $eax = COPY %op(s32)
- ; CHECK-NEXT: RET implicit $eax
- %x:_(s32) = COPY $eax
- %cst:_(s32) = G_CONSTANT i32 1
- %op:_(s32) = nuw G_SUB %x(s32), %cst
- $eax = COPY %op(s32)
- RET implicit $eax
-...
----
-name: sub_to_add_nsw_128
-body: |
- bb.0:
- liveins: $eax, $ebx
-
- ; CHECK-LABEL: name: sub_to_add_nsw_128
- ; CHECK: liveins: $eax, $ebx
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %a:_(s32) = COPY $eax
- ; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32)
- ; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128
- ; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c
- ; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8)
- ; CHECK-NEXT: $eax = COPY %d(s32)
- ; CHECK-NEXT: RET implicit $rax
- %a:_(s32) = COPY $eax
- %b:_(s8) = G_TRUNC %a
- %c:_(s8) = G_CONSTANT i8 -128
- %add:_(s8) = nsw nuw G_SUB %b, %c
- %d:_(s32) = G_ZEXT %add
- $eax = COPY %d
- RET implicit $rax
-...
----
-name: sub_to_add_nsw_intmin
-body: |
- bb.0:
- liveins: $eax, $ebx
-
- ; CHECK-LABEL: name: sub_to_add_nsw_intmin
- ; CHECK: liveins: $eax, $ebx
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %a:_(s32) = COPY $eax
- ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648
- ; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c
- ; CHECK-NEXT: $eax = COPY %add(s32)
- ; CHECK-NEXT: RET implicit $rax
- %a:_(s32) = COPY $eax
- %c:_(s32) = G_CONSTANT i32 -2147483648
- %add:_(s32) = nsw nuw G_SUB %a, %c
- $eax = COPY %add
- RET implicit $rax
-...
>From 39495c2875e2140d9f82ff300d7425c6da0a1987 Mon Sep 17 00:00:00 2001
From: stomfaig <stomfaig at gmail.com>
Date: Fri, 1 May 2026 17:36:44 +0100
Subject: [PATCH 8/8] format
---
llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
index 18333944ce52b..d52bc3e19932a 100644
--- a/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/X86/GISel/X86PreLegalizerCombiner.cpp
@@ -190,8 +190,8 @@ X86PreLegalizerCombinerPass::run(MachineFunction &MF,
GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(MF);
MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
- X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(),
- RuleConfig, &MDT);
+ X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(), RuleConfig,
+ &MDT);
Impl.combineMachineInstrs();
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
More information about the llvm-commits
mailing list