[llvm] [GlobalISel] Migrate remaining generic wip_match_opcode combines to MIR-pattern. (PR #222851)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 23:21:00 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Vikash Gupta (vg0204)
<details>
<summary>Changes</summary>
This patch converts another batch of GlobalISel combine rules from hand-written C++ / wip_match_opcode matchers to declarative MIR patterns, preserving existing behavior.
- commute_constant_to_rhs, fold_binop_into_select, constant_fold_binop, propagate_undef_all_ops, insert_extract_vec_elt_out_of_bounds, indexed load/store, buildvector_identity_fold
- i2p_to_p2i, ptr_add_with_zero, merge_of_x_and_{undef,zero}
- funnel_shift_to_rotate, combine_minmax_nan, mulo_by_2 / mulo_by_0, adde_to_addo, match_addos / match_subo_no_overflow
- redundant_neg_operands, sub_add_reg, count_zero_to_zero_poison, avgfloor/avgceil, select_constant_cmp splat arms
Functional changes:
- extract_vector_element_with_build_vector{,_trunc}: bail on an out-of-bounds constant index instead of reading past the G_BUILD_VECTOR sources; the undef result is already handled by extract_vec_elt_out_of_bounds.
- AMDGPU s64 and/or with a 32-bit mask: do not narrow when both operands are constants, so constant_fold_binop folds the binop to a single constant instead.
---
Patch is 109.52 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/222851.diff
26 Files Affected:
- (modified) llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h (+5-87)
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+472-158)
- (modified) llvm/lib/CodeGen/GlobalISel/CMakeLists.txt (-1)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+4-356)
- (removed) llvm/lib/CodeGen/GlobalISel/CombinerHelperArtifacts.cpp (-85)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp (+16-11)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUCombine.td (+1-2)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUCombinerHelper.cpp (+11)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUCombinerHelper.h (+6)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/combine-adde-to-addo.mir (+155)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-mulo-with-2.mir (+1-1)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-shift-immed-mismatch-crash.mir (+4-4)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir (+2-2)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/prelegalizer-combiner-addo-zero.mir (+1-1)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/prelegalizer-combiner-mulo-zero.mir (+1-1)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-prop-extends-phi.mir (+2-2)
- (modified) llvm/test/CodeGen/AArch64/neon-shuffle-vector-tbl.ll (+1-1)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-binop-s64-with-s32-mask.mir (+3-3)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-extract-vector-load.mir (+6-4)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-fold-binop-into-select.mir (+2-2)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-foldable-fneg.mir (+2-2)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-fsub-fneg.mir (+7-7)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.postlegal.mir (+4-4)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.make.buffer.rsrc.ll (+2-2)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/no-ctlz-from-umul-to-lshr-in-postlegalizer.ll (+21-24)
- (modified) llvm/utils/gn/secondary/llvm/lib/CodeGen/GlobalISel/BUILD.gn (-1)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 6b80367d786a5..f287f066291ca 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -406,10 +406,6 @@ class CombinerHelper {
LLVM_ABI void applyCombineShlOfExtend(MachineInstr &MI,
const RegisterImmPair &MatchData) const;
- /// Fold away a merge of an unmerge of the corresponding values.
- LLVM_ABI bool matchCombineMergeUnmerge(MachineInstr &MI,
- Register &MatchInfo) const;
-
/// Reduce a shift by a constant to an unmerge and a shift on a half sized
/// type. This will not produce a shift smaller than \p TargetShiftSize.
LLVM_ABI bool matchCombineShiftToUnmerge(MachineInstr &MI,
@@ -455,24 +451,6 @@ class CombinerHelper {
LLVM_ABI bool matchConstantFoldUnaryIntOp(MachineInstr &MI,
BuildFnTy &MatchInfo) const;
- /// Transform PtrToInt(IntToPtr(x)) to x.
- LLVM_ABI void applyCombineP2IToI2P(MachineInstr &MI, Register &Reg) const;
-
- /// Transform G_ADD (G_PTRTOINT x), y -> G_PTRTOINT (G_PTR_ADD x, y)
- /// Transform G_ADD y, (G_PTRTOINT x) -> G_PTRTOINT (G_PTR_ADD x, y)
- LLVM_ABI bool
- matchCombineAddP2IToPtrAdd(MachineInstr &MI,
- std::pair<Register, bool> &PtrRegAndCommute) const;
- LLVM_ABI void
- applyCombineAddP2IToPtrAdd(MachineInstr &MI,
- std::pair<Register, bool> &PtrRegAndCommute) const;
-
- // Transform G_PTR_ADD (G_PTRTOINT C1), C2 -> C1 + C2
- LLVM_ABI bool matchCombineConstPtrAddToI2P(MachineInstr &MI,
- APInt &NewCst) const;
- LLVM_ABI void applyCombineConstPtrAddToI2P(MachineInstr &MI,
- APInt &NewCst) const;
-
/// Transform anyext(trunc(x)) to x.
LLVM_ABI bool matchCombineAnyExtTrunc(MachineInstr &MI, Register &Reg) const;
@@ -500,19 +478,9 @@ class CombinerHelper {
/// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
LLVM_ABI bool matchUndefShuffleVectorMask(MachineInstr &MI) const;
- /// Return true if a G_STORE instruction \p MI is storing an undef value.
- LLVM_ABI bool matchUndefStore(MachineInstr &MI) const;
-
- /// Return true if a G_SELECT instruction \p MI has an undef comparison.
- LLVM_ABI bool matchUndefSelectCmp(MachineInstr &MI) const;
-
/// Return true if a G_{EXTRACT,INSERT}_VECTOR_ELT has an out of range index.
LLVM_ABI bool matchInsertExtractVecEltOutOfBounds(MachineInstr &MI) const;
- /// Return true if a G_SELECT instruction \p MI has a constant comparison. If
- /// true, \p OpIdx will store the operand index of the known selected value.
- LLVM_ABI bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx) const;
-
/// Replace an instruction with a G_FCONSTANT with value \p C.
LLVM_ABI void replaceInstWithFConstant(MachineInstr &MI, double C) const;
@@ -575,14 +543,6 @@ class CombinerHelper {
/// Erase \p MI
LLVM_ABI void eraseInst(MachineInstr &MI) const;
- /// Return true if MI is a G_ADD which can be simplified to a G_SUB.
- LLVM_ABI bool
- matchSimplifyAddToSub(MachineInstr &MI,
- std::tuple<Register, Register> &MatchInfo) const;
- LLVM_ABI void
- applySimplifyAddToSub(MachineInstr &MI,
- std::tuple<Register, Register> &MatchInfo) const;
-
/// Fold `a bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)`
LLVM_ABI bool matchBinopWithNeg(MachineInstr &MI, BuildFnTy &MatchInfo) const;
@@ -644,8 +604,8 @@ class CombinerHelper {
std::pair<Register, Register> &MatchInfo) const;
///}
- /// Combine G_PTR_ADD with nullptr to G_INTTOPTR
- LLVM_ABI bool matchPtrAddZero(MachineInstr &MI) const;
+ /// Combine a vector G_PTR_ADD with a zero splat to G_INTTOPTR.
+ LLVM_ABI bool matchPtrAddZeroVector(MachineInstr &MI) const;
/// Combine G_UREM x, (known power of 2) to an add and bitmasking.
LLVM_ABI void applySimplifyURemByPow2(MachineInstr &MI) const;
@@ -707,8 +667,6 @@ class CombinerHelper {
LLVM_ABI bool matchOrShiftToFunnelShift(MachineInstr &MI,
bool AllowScalarConstants,
BuildFnTy &MatchInfo) const;
- LLVM_ABI bool matchFunnelShiftToRotate(MachineInstr &MI) const;
- LLVM_ABI void applyFunnelShiftToRotate(MachineInstr &MI) const;
LLVM_ABI bool matchRotateOutOfRange(MachineInstr &MI) const;
LLVM_ABI void applyRotateOutOfRange(MachineInstr &MI) const;
@@ -846,32 +804,11 @@ class CombinerHelper {
LLVM_ABI bool matchTruncUSatUToFPTOUISat(MachineInstr &MI,
MachineInstr &SrcMI) const;
- /// Match:
- /// (G_UMULO x, 2) -> (G_UADDO x, x)
- /// (G_SMULO x, 2) -> (G_SADDO x, x)
- LLVM_ABI bool matchMulOBy2(MachineInstr &MI, BuildFnTy &MatchInfo) const;
-
/// Match:
/// (G_*MULO x, 0) -> 0 + no carry out
LLVM_ABI bool matchMulOBy0(MachineInstr &MI, BuildFnTy &MatchInfo) const;
- /// Match:
- /// (G_*ADDE x, y, 0) -> (G_*ADDO x, y)
- /// (G_*SUBE x, y, 0) -> (G_*SUBO x, y)
- LLVM_ABI bool matchAddEToAddO(MachineInstr &MI, BuildFnTy &MatchInfo) const;
-
- /// Transform (fadd x, fneg(y)) -> (fsub x, y)
- /// (fadd fneg(x), y) -> (fsub y, x)
- /// (fsub x, fneg(y)) -> (fadd x, y)
- /// (fmul fneg(x), fneg(y)) -> (fmul x, y)
- /// (fdiv fneg(x), fneg(y)) -> (fdiv x, y)
- /// (fmad fneg(x), fneg(y), z) -> (fmad x, y, z)
- /// (fma fneg(x), fneg(y), z) -> (fma x, y, z)
- LLVM_ABI bool matchRedundantNegOperands(MachineInstr &MI,
- BuildFnTy &MatchInfo) const;
-
- LLVM_ABI bool matchFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
- LLVM_ABI void applyFsubToFneg(MachineInstr &MI, Register &MatchInfo) const;
+ LLVM_ABI bool matchFsubToFneg(MachineInstr &MI) const;
LLVM_ABI bool canCombineFMadOrFMA(MachineInstr &MI, bool &AllowFusionGlobally,
bool &HasFMAD, bool &Aggressive,
@@ -927,8 +864,6 @@ class CombinerHelper {
matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI,
BuildFnTy &MatchInfo) const;
- LLVM_ABI bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const;
-
LLVM_ABI bool
matchRepeatedFPDivisor(MachineInstr &MI,
SmallVector<MachineInstr *> &MatchInfo) const;
@@ -992,9 +927,6 @@ class CombinerHelper {
/// Match constant LHS FP ops that should be commuted.
LLVM_ABI bool matchCommuteFPConstantToRHS(MachineInstr &MI) const;
- // Given a binop \p MI, commute operands 1 and 2.
- LLVM_ABI void applyCommuteBinOpOperands(MachineInstr &MI) const;
-
/// Combine select to integer min/max.
LLVM_ABI bool matchSelectIMinMax(const MachineOperand &MO,
BuildFnTy &MatchInfo) const;
@@ -1024,8 +956,7 @@ class CombinerHelper {
LLVM_ABI bool matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) const;
/// Combine extract vector element.
- LLVM_ABI bool matchExtractVectorElement(MachineInstr &MI,
- BuildFnTy &MatchInfo) const;
+ LLVM_ABI bool matchExtractVectorElement(MachineInstr &MI) const;
/// Combine extract vector element with a build vector on the vector register.
LLVM_ABI bool
@@ -1074,8 +1005,7 @@ class CombinerHelper {
LLVM_ABI void applyExpandFPowI(MachineInstr &MI, int64_t Exponent) const;
/// Combine insert vector element OOB.
- LLVM_ABI bool matchInsertVectorElementOOB(MachineInstr &MI,
- BuildFnTy &MatchInfo) const;
+ LLVM_ABI bool matchInsertVectorElementOOB(MachineInstr &MI) const;
LLVM_ABI bool
matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI,
@@ -1134,14 +1064,6 @@ class CombinerHelper {
LLVM_ABI bool matchUnmergeValuesAnyExtBuildVector(const MachineInstr &MI,
BuildFnTy &MatchInfo) const;
- // merge_values(_, undef) -> anyext
- LLVM_ABI bool matchMergeXAndUndef(const MachineInstr &MI,
- BuildFnTy &MatchInfo) const;
-
- // merge_values(_, zero) -> zext
- LLVM_ABI bool matchMergeXAndZero(const MachineInstr &MI,
- BuildFnTy &MatchInfo) const;
-
// overflow sub
LLVM_ABI bool matchSuboCarryOut(const MachineInstr &MI,
BuildFnTy &MatchInfo) const;
@@ -1154,11 +1076,7 @@ class CombinerHelper {
// (ctlz (or (shl (xor x, (sra x, bitwidth-1)), 1), 1) -> (ctls x)
LLVM_ABI bool matchCtls(MachineInstr &CtlzMI, BuildFnTy &MatchInfo) const;
- LLVM_ABI bool matchAVG(MachineInstr &MI, MachineRegisterInfo &MRI, Register X,
- Register Y, unsigned TargetOpc) const;
-
LLVM_ABI bool matchCountZeroToZeroPoison(MachineInstr &MI) const;
- LLVM_ABI void applyCountZeroToZeroPoison(MachineInstr &MI) const;
private:
/// Checks for legality of an indexed variant of \p LdSt.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3735e95ee8f68..4c40e8c8c8b38 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -243,11 +243,15 @@ def push_freeze_to_prevent_poison_from_propagating : GICombineRule<
[{ return !isGuaranteedNotToBePoison(${src}.getReg(), MRI) && Helper.matchFreezeOfSingleMaybePoisonOperand(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+def extending_loads_frags : GICombinePatFrag<
+ (outs root:$dst), (ins),
+ !foreach(op, [G_LOAD, G_SEXTLOAD, G_ZEXTLOAD],
+ (pattern (op $dst, $ptr)))>;
def extending_loads : GICombineRule<
(defs root:$root, extending_load_matchdata:$matchinfo),
- (match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD):$root,
- [{ return Helper.matchCombineExtendingLoads(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.applyCombineExtendingLoads(*${root}, ${matchinfo}); }])>;
+ (match (extending_loads_frags $root):$mi,
+ [{ return Helper.matchCombineExtendingLoads(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyCombineExtendingLoads(*${mi}, ${matchinfo}); }])>;
def load_and_mask : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
@@ -290,11 +294,22 @@ def combine_extracted_vector_load : GICombineRule<
[{ return Helper.matchCombineExtractedVectorLoad(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
-def combine_indexed_load_store : GICombineRule<
+def combine_indexed_load_frags : GICombinePatFrag<
+ (outs root:$dst), (ins),
+ !foreach(op, [G_LOAD, G_SEXTLOAD, G_ZEXTLOAD],
+ (pattern (op $dst, $ptr)))>;
+def combine_indexed_load : GICombineRule<
(defs root:$root, indexed_load_store_matchdata:$matchinfo),
- (match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD, G_STORE):$root,
+ (match (combine_indexed_load_frags $root):$mi,
+ [{ return Helper.matchCombineIndexedLoadStore(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyCombineIndexedLoadStore(*${mi}, ${matchinfo}); }])>;
+def combine_indexed_store : GICombineRule<
+ (defs root:$root, indexed_load_store_matchdata:$matchinfo),
+ (match (G_STORE $val, $ptr):$root,
[{ return Helper.matchCombineIndexedLoadStore(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyCombineIndexedLoadStore(*${root}, ${matchinfo}); }])>;
+def combine_indexed_load_store : GICombineGroup<[combine_indexed_load,
+ combine_indexed_store]>;
def memcpy_family_matchinfo : GIDefMatchData<"MemCpyFamilyLoweringInfo">;
def combine_memcpy_inline : GICombineRule<
@@ -368,22 +383,29 @@ def shifts_too_big : GICombineRule<
}
}])>;
+// Shared frag for the shift-chain rules below: all shift opcodes that have a
+// (dst, base, amount) shape.
+def shift_chain_frags : GICombinePatFrag<
+ (outs root:$dst), (ins),
+ !foreach(op, [G_SHL, G_ASHR, G_LSHR, G_SSHLSAT, G_USHLSAT],
+ (pattern (op $dst, $base, $amt)))>;
+
// Fold shift (shift base x), y -> shift base, (x+y), if shifts are same
def shift_immed_matchdata : GIDefMatchData<"RegisterImmPair">;
def shift_immed_chain : GICombineRule<
(defs root:$d, shift_immed_matchdata:$matchinfo),
- (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_SSHLSAT, G_USHLSAT):$d,
- [{ return Helper.matchShiftImmedChain(*${d}, ${matchinfo}); }]),
- (apply [{ Helper.applyShiftImmedChain(*${d}, ${matchinfo}); }])>;
+ (match (shift_chain_frags $d):$mi,
+ [{ return Helper.matchShiftImmedChain(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyShiftImmedChain(*${mi}, ${matchinfo}); }])>;
// Transform shift (logic (shift X, C0), Y), C1
// -> logic (shift X, (C0+C1)), (shift Y, C1), if shifts are same
def shift_of_shifted_logic_matchdata : GIDefMatchData<"ShiftOfShiftedLogic">;
def shift_of_shifted_logic_chain : GICombineRule<
(defs root:$d, shift_of_shifted_logic_matchdata:$matchinfo),
- (match (wip_match_opcode G_SHL, G_ASHR, G_LSHR, G_USHLSAT, G_SSHLSAT):$d,
- [{ return Helper.matchShiftOfShiftedLogic(*${d}, ${matchinfo}); }]),
- (apply [{ Helper.applyShiftOfShiftedLogic(*${d}, ${matchinfo}); }])>;
+ (match (shift_chain_frags $d):$mi,
+ [{ return Helper.matchShiftOfShiftedLogic(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyShiftOfShiftedLogic(*${mi}, ${matchinfo}); }])>;
def mul_to_shl : GICombineRule<
(defs root:$d, unsigned_matchinfo:$matchinfo),
@@ -537,7 +559,7 @@ def binop_right_undef_to_undef_frags : binop_right_undef_frag<[G_SHL, G_ASHR, G_
def binop_right_undef_to_undef: GICombineRule<
(defs root:$dst),
(match (binop_right_undef_to_undef_frags $dst)),
- (apply [{ Helper.replaceInstWithUndef(*${dst}.getParent()); }])>;
+ (apply (G_IMPLICIT_DEF $dst))>;
def unary_undef_to_zero_frags : unary_undef_frag<[G_ABS]>;
def unary_undef_to_zero: GICombineRule<
@@ -550,7 +572,7 @@ def unary_undef_to_undef_frags : unary_undef_frag<
def unary_undef_to_undef : GICombineRule<
(defs root:$dst),
(match (unary_undef_to_undef_frags $dst)),
- (apply [{ Helper.replaceInstWithUndef(*${dst}.getParent()); }])>;
+ (apply (G_IMPLICIT_DEF $dst))>;
// Instructions where if any source operand is undef, the instruction can be
// replaced with undef.
@@ -558,15 +580,21 @@ def propagate_undef_any_op_frags : binop_any_undef_frag<[G_ADD, G_SUB, G_XOR]>;
def propagate_undef_any_op: GICombineRule<
(defs root:$dst),
(match (propagate_undef_any_op_frags $dst)),
- (apply [{ Helper.replaceInstWithUndef(*${dst}.getParent()); }])>;
+ (apply (G_IMPLICIT_DEF $dst))>;
-// Instructions where if all source operands are undef, the instruction can be
-// replaced with undef.
-def propagate_undef_all_ops: GICombineRule<
+def propagate_undef_all_ops_shuffle_vector: GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_SHUFFLE_VECTOR, G_BUILD_VECTOR):$root,
- [{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
- (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+ (match (G_SHUFFLE_VECTOR $root, $src1, $src2, $mask):$mi,
+ [{ return Helper.matchAllExplicitUsesAreUndef(*${mi}); }]),
+ (apply (G_IMPLICIT_DEF $root))>;
+def propagate_undef_all_ops_build_vector: GICombineRule<
+ (defs root:$root),
+ (match (G_BUILD_VECTOR $root, GIVariadic<>:$srcs):$mi,
+ [{ return Helper.matchAllExplicitUsesAreUndef(*${mi}); }]),
+ (apply (G_IMPLICIT_DEF $root))>;
+
+def propagate_undef_all_ops: GICombineGroup<[propagate_undef_all_ops_shuffle_vector,
+ propagate_undef_all_ops_build_vector]>;
// Replace a G_SHUFFLE_VECTOR with an undef mask with a G_IMPLICIT_DEF.
def propagate_undef_shuffle_mask: GICombineRule<
@@ -575,12 +603,20 @@ def propagate_undef_shuffle_mask: GICombineRule<
[{ return Helper.matchUndefShuffleVectorMask(*${root}); }]),
(apply (G_IMPLICIT_DEF $dst))>;
- // Replace an insert/extract element of an out of bounds index with undef.
- def insert_extract_vec_elt_out_of_bounds : GICombineRule<
+def insert_vec_elt_out_of_bounds : GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_INSERT_VECTOR_ELT, G_EXTRACT_VECTOR_ELT):$root,
- [{ return Helper.matchInsertExtractVecEltOutOfBounds(*${root}); }]),
- (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+ (match (G_INSERT_VECTOR_ELT $root, $vec, $elt, $idx):$mi,
+ [{ return Helper.matchInsertExtractVecEltOutOfBounds(*${mi}); }]),
+ (apply (G_IMPLICIT_DEF $root))>;
+def extract_vec_elt_out_of_bounds : GICombineRule<
+ (defs root:$root),
+ (match (G_EXTRACT_VECTOR_ELT $root, $vec, $idx):$mi,
+ [{ return Helper.matchInsertExtractVecEltOutOfBounds(*${mi}); }]),
+ (apply (G_IMPLICIT_DEF $root))>;
+
+// Replace an insert/extract element of an out of bounds index with undef.
+def insert_extract_vec_elt_out_of_bounds : GICombineGroup<[
+ insert_vec_elt_out_of_bounds, extract_vec_elt_out_of_bounds]>;
// Fold (cond ? x : x) -> x
// _trivial: arms are the same register; _equiv: arms are provably equivalent.
@@ -619,15 +655,26 @@ def select_constant_cmp_true : GICombineRule<
(apply (GIReplaceReg $dst, $tval))
>;
-def select_constant_cmp_general: GICombineRule<
- (defs root:$root, unsigned_matchinfo:$matchinfo),
+def select_constant_cmp_general_false: GICombineRule<
+ (defs root:$dst),
(match (G_SELECT $dst, $cond, $tval, $fval):$root,
- [{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
- (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
->;
+ [{
+ auto C = isConstantOrConstantSplatVector(${cond}.getReg(), MRI);
+ return C && C->isZero();
+ }]),
+ (apply (COPY $dst, $fval))>;
+def select_constant_cmp_general_true: GICombineRule<
+ (defs root:$dst),
+ (match (G_SELECT $dst, $cond, $tval, $fval):$root,
+ [{
+ auto C = isConstantOrConstantSplatVector(${cond}.getReg(), MRI);
+ return C && !C->isZero();
+ }]),
+ (apply (COPY $dst, $tval))>;
def select_constant_cmp : GICombineGroup<[select_constant_cmp_false,
select_constant_cmp_true,
- select_constant_cmp_general]>;
+ select_constant_cmp_general_false,
+ select_constant_cmp_general_true]>;
// select c, 0, x -> and (not c), x
// Skip constant c: select_constant_cmp folds it directly, avoiding the freeze.
@@ -665,25 +712,65 @@ def select_not: GICombineRule<
// Fold (C op x) -> (x op C)
// TODO: handle more isCommutable opcodes
// TODO: handle compares (currently not marked as isCommutable)
-def commute_int_constant_to_rhs : GICombineRule<
+// The commutable integer opcodes have three operand shapes: plain 2-use
+// single-def binops, 3-use [su]mulfix ops with a scale operand, and two-def
+// overflow ops.
+class commute_int_binop_rule<Instruction op> : GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_ADD, G_MUL, G_AND, G_OR, G_XOR,
- G_SMIN, G_SMAX, G_UMIN, G_UMAX, G_UADDO, G_SADDO,
- G_UMULO, G_SMULO, G_UMULH, G_SMULH,
- G_UADDSAT, G_SADDSAT, G_SMULFIX, G_UMULFIX,
- G_SMULFIXSAT, G_UMULFIXSAT):$root,
+ (match (op $dst, $lhs, $rhs):$root,
[{ return Helper.matchCommuteConstantToRHS(*${root}); }]),
- (apply [{ Helper.applyCommuteBinOpOperands(*${root}); }])
->;
+ (apply (op $dst, $rhs, $lhs, (MIFlags $root)))>;
+
+class commute_int_mulfix_rule<Instruction op> : GICombineRule<
+ (defs root:$root),
+ (match (op $dst, $lhs, $rhs, $scale):$root,
+ [{ return Helper.matchCommuteConstantToRHS(*${root}); }]),
+ (apply (op $dst, $rhs, $lhs, $scale, (MIFlags $root)))>;
-def commute_fp_constant_to_rhs : GICombineRule<
+class commute_int_overflow_rule<Instruction op> : GICombineRule<
(defs root:$root),
- (match (wip_match_opcode G_FADD, G_FMUL, G_FMINNUM, G_FMAX...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/222851
More information about the llvm-commits
mailing list