Skip to content

Commit 3fbe241

Browse files
committed
[GlobalIsel] Combine G_SELECT
Cleanups, preparation for more combines, add known bits for constant conditions, combine selects where the false and true register are constants, and improve support for vector conditions. AMDGPU supports vector conditions. X86 has a todo for vector conditions. AArch64 SVE supports SEL for vector conditions. How to implement vector conditions with NEON (with bsl), see arm64-vselect.ll ? Vector select asserts in the instruction selector. buildNot does not support scalable vectors. We cannot create scalable constant vectors of -1 and there is no G_Not. AArch64 SVE has a NOT and a DUP for broadcasting. Something akin to G_CONSTANT_SPLAT, G_CONSTANT_VECTOR, G_SPLAT_VECTOR, G_BRODCAST, or G_HOMOGENOUS_VECTOR that takes an immediate and creates a (fixed or scalable) vector where all elements are the immediate might solve the buildNot challenge, facilitates new combines, pattern matching, and new selecting optimizations. P.S. We need to support integer and float. llvm#74502 ```c <vscale x 4 x i32> splat (i32 -1) ```
1 parent 04c4566 commit 3fbe241

31 files changed

+5247
-4251
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -423,16 +423,9 @@ class CombinerHelper {
423423
/// Return true if a G_STORE instruction \p MI is storing an undef value.
424424
bool matchUndefStore(MachineInstr &MI);
425425

426-
/// Return true if a G_SELECT instruction \p MI has an undef comparison.
427-
bool matchUndefSelectCmp(MachineInstr &MI);
428-
429426
/// Return true if a G_{EXTRACT,INSERT}_VECTOR_ELT has an out of range index.
430427
bool matchInsertExtractVecEltOutOfBounds(MachineInstr &MI);
431428

432-
/// Return true if a G_SELECT instruction \p MI has a constant comparison. If
433-
/// true, \p OpIdx will store the operand index of the known selected value.
434-
bool matchConstantSelectCmp(MachineInstr &MI, unsigned &OpIdx);
435-
436429
/// Replace an instruction with a G_FCONSTANT with value \p C.
437430
void replaceInstWithFConstant(MachineInstr &MI, double C);
438431

@@ -771,9 +764,6 @@ class CombinerHelper {
771764
bool matchCombineFSubFpExtFNegFMulToFMadOrFMA(MachineInstr &MI,
772765
BuildFnTy &MatchInfo);
773766

774-
/// Fold boolean selects to logical operations.
775-
bool matchSelectToLogical(MachineInstr &MI, BuildFnTy &MatchInfo);
776-
777767
bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info);
778768

779769
/// Transform G_ADD(x, G_SUB(y, x)) to y.
@@ -816,6 +806,9 @@ class CombinerHelper {
816806
// Given a binop \p MI, commute operands 1 and 2.
817807
void applyCommuteBinOpOperands(MachineInstr &MI);
818808

809+
// Combine selects.
810+
bool matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo);
811+
819812
private:
820813
/// Checks for legality of an indexed variant of \p LdSt.
821814
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
@@ -906,6 +899,21 @@ class CombinerHelper {
906899
/// select (fcmp uge x, 1.0) 1.0, x -> fminnm x, 1.0
907900
bool matchFPSelectToMinMax(Register Dst, Register Cond, Register TrueVal,
908901
Register FalseVal, BuildFnTy &MatchInfo);
902+
903+
bool isOneOrOneSplat(Register Src, bool AllowUndefs);
904+
bool isZeroOrZeroSplat(Register Src, bool AllowUndefs);
905+
bool isConstantSplatVector(Register Src, int64_t SplatValue,
906+
bool AllowUndefs);
907+
std::optional<APInt> getConstantOrConstantSplatVector(Register Src);
908+
909+
/// Try to combine selects with constant conditions.
910+
bool tryCombineSelectConstantCondition(GSelect *Select, BuildFnTy &MatchInfo);
911+
912+
/// Try to combine selects with boolean conditions to logical operators.
913+
bool tryFoldBoolSelectToLogic(GSelect *Select, BuildFnTy &MatchInfo);
914+
915+
/// Try to combine selects where the true and false values are constant.
916+
bool tryFoldSelectOfConstants(GSelect *Select, BuildFnTy &MatchInfo);
909917
};
910918
} // namespace llvm
911919

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,11 +1701,11 @@ class MachineIRBuilder {
17011701

17021702
/// Build and insert a bitwise not,
17031703
/// \p NegOne = G_CONSTANT -1
1704-
/// \p Res = G_OR \p Op0, NegOne
1705-
MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0) {
1706-
auto NegOne = buildConstant(Dst.getLLTTy(*getMRI()), -1);
1707-
return buildInstr(TargetOpcode::G_XOR, {Dst}, {Src0, NegOne});
1708-
}
1704+
/// \p Res = G_XOR \p Op0, NegOne
1705+
/// Or
1706+
/// \p NegOne = G_BUILD_VECTOR -1, -1, -1, ...
1707+
/// \p Res = G_XOR \p Op0, NegOne
1708+
MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0);
17091709

17101710
/// Build and insert integer negation
17111711
/// \p Zero = G_CONSTANT 0

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,6 @@ def select_same_val: GICombineRule<
419419
(apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
420420
>;
421421

422-
// Fold (undef ? x : y) -> y
423-
def select_undef_cmp: GICombineRule<
424-
(defs root:$dst),
425-
(match (G_IMPLICIT_DEF $undef),
426-
(G_SELECT $dst, $undef, $x, $y)),
427-
(apply (GIReplaceReg $dst, $y))
428-
>;
429-
430-
// Fold (true ? x : y) -> x
431-
// Fold (false ? x : y) -> y
432-
def select_constant_cmp_matchdata : GIDefMatchData<"unsigned">;
433-
def select_constant_cmp: GICombineRule<
434-
(defs root:$root, select_constant_cmp_matchdata:$matchinfo),
435-
(match (wip_match_opcode G_SELECT):$root,
436-
[{ return Helper.matchConstantSelectCmp(*${root}, ${matchinfo}); }]),
437-
(apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${matchinfo}); }])
438-
>;
439-
440-
def select_to_logical : GICombineRule<
441-
(defs root:$root, build_fn_matchinfo:$matchinfo),
442-
(match (wip_match_opcode G_SELECT):$root,
443-
[{ return Helper.matchSelectToLogical(*${root}, ${matchinfo}); }]),
444-
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])
445-
>;
446-
447422
// Fold (C op x) -> (x op C)
448423
// TODO: handle more isCommutable opcodes
449424
// TODO: handle compares (currently not marked as isCommutable)
@@ -1242,6 +1217,12 @@ def select_to_minmax: GICombineRule<
12421217
[{ return Helper.matchSimplifySelectToMinMax(*${root}, ${info}); }]),
12431218
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
12441219

1220+
def match_selects : GICombineRule<
1221+
(defs root:$root, build_fn_matchinfo:$matchinfo),
1222+
(match (wip_match_opcode G_SELECT):$root,
1223+
[{ return Helper.matchSelect(*${root}, ${matchinfo}); }]),
1224+
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
1225+
12451226
// FIXME: These should use the custom predicate feature once it lands.
12461227
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
12471228
undef_to_negative_one,
@@ -1281,8 +1262,7 @@ def width_reduction_combines : GICombineGroup<[reduce_shl_of_extend,
12811262

12821263
def phi_combines : GICombineGroup<[extend_through_phis]>;
12831264

1284-
def select_combines : GICombineGroup<[select_undef_cmp, select_constant_cmp,
1285-
select_to_logical]>;
1265+
def select_combines : GICombineGroup<[match_selects]>;
12861266

12871267
def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl, add_p2i_to_ptradd,
12881268
mul_by_neg_one, idempotent_prop]>;

0 commit comments

Comments
 (0)