Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,23 @@ class CombinerHelper {
bool matchUMulHToLShr(MachineInstr &MI) const;
void applyUMulHToLShr(MachineInstr &MI) const;

// Combine trunc(smin(smax(x, C1), C2)) -> truncssat_s(x)
// or trunc(smax(smin(x, C2), C1)) -> truncssat_s(x).
bool matchTruncSSatS(MachineInstr &MI, Register &MatchInfo) const;
void applyTruncSSatS(MachineInstr &MI, Register &MatchInfo) const;

// Combine trunc(smin(smax(x, 0), C)) -> truncssat_u(x)
// or trunc(smax(smin(x, C), 0)) -> truncssat_u(x)
// or trunc(umin(smax(x, 0), C)) -> truncssat_u(x)
bool matchTruncSSatU(MachineInstr &MI, Register &MatchInfo) const;
void applyTruncSSatU(MachineInstr &MI, Register &MatchInfo) const;

// Combine trunc(umin(x, C)) -> truncusat_u(x).
bool matchTruncUSatU(MachineInstr &MI, MachineInstr &MinMI) const;

// Combine truncusat_u(fptoui(x)) -> fptoui_sat(x)
bool matchTruncUSatUToFPTOUISat(MachineInstr &MI, MachineInstr &SrcMI) const;

/// Try to transform \p MI by using all of the above
/// combine functions. Returns true if changed.
bool tryCombine(MachineInstr &MI) const;
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,9 @@ class GCastOp : public GenericMachineInstr {
case TargetOpcode::G_SEXT:
case TargetOpcode::G_SITOFP:
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_TRUNC_SSAT_S:
case TargetOpcode::G_TRUNC_SSAT_U:
case TargetOpcode::G_TRUNC_USAT_U:
case TargetOpcode::G_UITOFP:
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_ANYEXT:
Expand Down
31 changes: 30 additions & 1 deletion llvm/include/llvm/Target/GlobalISel/Combine.td
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,35 @@ def mulh_to_lshr : GICombineRule<

def mulh_combines : GICombineGroup<[mulh_to_lshr]>;

def trunc_ssats : GICombineRule<
(defs root:$root, register_matchinfo:$matchinfo),
(match (G_TRUNC $dst, $src):$root,
[{ return Helper.matchTruncSSatS(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyTruncSSatS(*${root}, ${matchinfo}); }])>;

def trunc_ssatu : GICombineRule<
(defs root:$root, register_matchinfo:$matchinfo),
(match (G_TRUNC $dst, $src):$root,
[{ return Helper.matchTruncSSatU(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyTruncSSatU(*${root}, ${matchinfo}); }])>;

def trunc_usatu : GICombineRule<
(defs root:$root),
(match (G_UMIN $min, $x, $y):$Min,
(G_TRUNC $dst, $min):$root,
[{ return Helper.matchTruncUSatU(*${root}, *${Min}); }]),
(apply (G_TRUNC_USAT_U $dst, $x))>;

def truncusatu_to_fptouisat : GICombineRule<
(defs root:$root),
(match (G_FPTOUI $src, $x):$Src,
(G_TRUNC_USAT_U $dst, $src):$root,
[{ return Helper.matchTruncUSatUToFPTOUISat(*${root}, *${Src}); }]),
(apply (G_FPTOUI_SAT $dst, $x))
>;

def truncsat_combines : GICombineGroup<[trunc_ssats, trunc_ssatu, trunc_usatu, truncusatu_to_fptouisat]>;

def redundant_neg_operands: GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (wip_match_opcode G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMAD, G_FMA):$root,
Expand Down Expand Up @@ -2067,7 +2096,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
simplify_neg_minmax, combine_concat_vector,
sext_trunc, zext_trunc, prefer_sign_combines, shuffle_combines,
combine_use_vector_truncate, merge_combines, overflow_combines]>;
combine_use_vector_truncate, merge_combines, overflow_combines, truncsat_combines]>;

// A combine group used to for prelegalizer combiners at -O0. The combines in
// this group have been selected based on experiments to balance code size and
Expand Down
90 changes: 90 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5924,6 +5924,96 @@ void CombinerHelper::applyUMulHToLShr(MachineInstr &MI) const {
MI.eraseFromParent();
}

bool CombinerHelper::matchTruncSSatS(MachineInstr &MI,
Register &MatchInfo) const {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
LLT DstTy = MRI.getType(Dst);
LLT SrcTy = MRI.getType(Src);
unsigned NumDstBits = DstTy.getScalarSizeInBits();
unsigned NumSrcBits = SrcTy.getScalarSizeInBits();
assert(NumSrcBits > NumDstBits && "Unexpected types for truncate operation");

if (!LI || !isLegal({TargetOpcode::G_TRUNC_SSAT_S, {DstTy, SrcTy}}))
return false;

APInt SignedMax = APInt::getSignedMaxValue(NumDstBits).sext(NumSrcBits);
APInt SignedMin = APInt::getSignedMinValue(NumDstBits).sext(NumSrcBits);
return mi_match(Src, MRI,
m_GSMin(m_GSMax(m_Reg(MatchInfo),
m_SpecificICstOrSplat(SignedMin)),
m_SpecificICstOrSplat(SignedMax))) ||
mi_match(Src, MRI,
m_GSMax(m_GSMin(m_Reg(MatchInfo),
m_SpecificICstOrSplat(SignedMax)),
m_SpecificICstOrSplat(SignedMin)));
}

void CombinerHelper::applyTruncSSatS(MachineInstr &MI,
Register &MatchInfo) const {
Register Dst = MI.getOperand(0).getReg();
Builder.buildTruncSSatS(Dst, MatchInfo);
MI.eraseFromParent();
}

bool CombinerHelper::matchTruncSSatU(MachineInstr &MI,
Register &MatchInfo) const {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
LLT DstTy = MRI.getType(Dst);
LLT SrcTy = MRI.getType(Src);
unsigned NumDstBits = DstTy.getScalarSizeInBits();
unsigned NumSrcBits = SrcTy.getScalarSizeInBits();
assert(NumSrcBits > NumDstBits && "Unexpected types for truncate operation");

if (!LI || !isLegal({TargetOpcode::G_TRUNC_SSAT_U, {DstTy, SrcTy}}))
return false;
APInt UnsignedMax = APInt::getMaxValue(NumDstBits).zext(NumSrcBits);
return mi_match(Src, MRI,
m_GSMin(m_GSMax(m_Reg(MatchInfo), m_SpecificICstOrSplat(0)),
m_SpecificICstOrSplat(UnsignedMax))) ||
mi_match(Src, MRI,
m_GSMax(m_GSMin(m_Reg(MatchInfo),
m_SpecificICstOrSplat(UnsignedMax)),
m_SpecificICstOrSplat(0))) ||
mi_match(Src, MRI,
m_GUMin(m_GSMax(m_Reg(MatchInfo), m_SpecificICstOrSplat(0)),
m_SpecificICstOrSplat(UnsignedMax)));
}

void CombinerHelper::applyTruncSSatU(MachineInstr &MI,
Register &MatchInfo) const {
Register Dst = MI.getOperand(0).getReg();
Builder.buildTruncSSatU(Dst, MatchInfo);
MI.eraseFromParent();
}

bool CombinerHelper::matchTruncUSatU(MachineInstr &MI,
MachineInstr &MinMI) const {
Register Min = MinMI.getOperand(2).getReg();
Register Val = MinMI.getOperand(1).getReg();
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
LLT SrcTy = MRI.getType(Val);
unsigned NumDstBits = DstTy.getScalarSizeInBits();
unsigned NumSrcBits = SrcTy.getScalarSizeInBits();
assert(NumSrcBits > NumDstBits && "Unexpected types for truncate operation");

if (!LI || !isLegal({TargetOpcode::G_TRUNC_SSAT_U, {DstTy, SrcTy}}))
return false;
APInt UnsignedMax = APInt::getMaxValue(NumDstBits).zext(NumSrcBits);
return mi_match(Min, MRI, m_SpecificICstOrSplat(UnsignedMax)) &&
!mi_match(Val, MRI, m_GSMax(m_Reg(), m_Reg()));
}

bool CombinerHelper::matchTruncUSatUToFPTOUISat(MachineInstr &MI,
MachineInstr &SrcMI) const {
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
LLT SrcTy = MRI.getType(SrcMI.getOperand(1).getReg());

return LI &&
isLegalOrBeforeLegalizer({TargetOpcode::G_FPTOUI_SAT, {DstTy, SrcTy}});
}

bool CombinerHelper::matchRedundantNegOperands(MachineInstr &MI,
BuildFnTy &MatchInfo) const {
unsigned Opc = MI.getOpcode();
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Target/AArch64/AArch64Combine.td
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,10 @@ def AArch64PostLegalizerLowering
// Post-legalization combines which are primarily optimizations.
def AArch64PostLegalizerCombiner
: GICombiner<"AArch64PostLegalizerCombinerImpl",
[copy_prop, cast_of_cast_combines, buildvector_of_truncate,
integer_of_truncate, mutate_anyext_to_zext,
combines_for_extload, combine_indexed_load_store, sext_trunc_sextload,
[copy_prop, cast_of_cast_combines,
buildvector_of_truncate, integer_of_truncate,
mutate_anyext_to_zext, combines_for_extload,
combine_indexed_load_store, sext_trunc_sextload,
hoist_logic_op_with_same_opcode_hands,
redundant_and, xor_of_and_with_same_reg,
extractvecelt_pairwise_add, redundant_or,
Expand All @@ -367,5 +368,6 @@ def AArch64PostLegalizerCombiner
select_to_minmax, or_to_bsp, combine_concat_vector,
commute_constant_to_rhs, extract_vec_elt_combines,
push_freeze_to_prevent_poison_from_propagating,
combine_mul_cmlt, combine_use_vector_truncate, extmultomull]> {
combine_mul_cmlt, combine_use_vector_truncate,
extmultomull, truncsat_combines]> {
}
6 changes: 3 additions & 3 deletions llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1847,11 +1847,11 @@ bool AArch64LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
case Intrinsic::aarch64_neon_sdot:
return LowerTriOp(AArch64::G_SDOT);
case Intrinsic::aarch64_neon_sqxtn:
return LowerUnaryOp(AArch64::G_TRUNC_SSAT_S);
return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_S);
case Intrinsic::aarch64_neon_sqxtun:
return LowerUnaryOp(AArch64::G_TRUNC_SSAT_U);
return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_U);
case Intrinsic::aarch64_neon_uqxtn:
return LowerUnaryOp(AArch64::G_TRUNC_USAT_U);
return LowerUnaryOp(TargetOpcode::G_TRUNC_USAT_U);

case Intrinsic::vector_reverse:
// TODO: Add support for vector_reverse
Expand Down
Loading