Skip to content

Commit 737e0bc

Browse files
author
Thorsten Schütt
authored
1 parent c5509fe commit 737e0bc

File tree

8 files changed

+522
-21
lines changed

8 files changed

+522
-21
lines changed

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,6 @@ class CombinerHelper {
599599
/// This variant does not erase \p MI after calling the build function.
600600
void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo);
601601

602-
/// Use a function which takes in a MachineIRBuilder to perform a combine.
603-
/// By default, it erases the instruction \p MI from the function.
604-
void applyBuildFnMO(const MachineOperand &MO, BuildFnTy &MatchInfo);
605-
606602
bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo);
607603
bool matchFunnelShiftToRotate(MachineInstr &MI);
608604
void applyFunnelShiftToRotate(MachineInstr &MI);
@@ -814,6 +810,12 @@ class CombinerHelper {
814810
/// Match constant LHS ops that should be commuted.
815811
bool matchCommuteConstantToRHS(MachineInstr &MI);
816812

813+
/// Combine sext of trunc.
814+
bool matchSextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo);
815+
816+
/// Combine zext of trunc.
817+
bool matchZextOfTrunc(const MachineOperand &MO, BuildFnTy &MatchInfo);
818+
817819
/// Match constant LHS FP ops that should be commuted.
818820
bool matchCommuteFPConstantToRHS(MachineInstr &MI);
819821

@@ -857,6 +859,9 @@ class CombinerHelper {
857859
/// register and different indices.
858860
bool matchExtractVectorElementWithDifferentIndices(const MachineOperand &MO,
859861
BuildFnTy &MatchInfo);
862+
/// Use a function which takes in a MachineIRBuilder to perform a combine.
863+
/// By default, it erases the instruction def'd on \p MO from the function.
864+
void applyBuildFnMO(const MachineOperand &MO, BuildFnTy &MatchInfo);
860865

861866
/// Combine insert vector element OOB.
862867
bool matchInsertVectorElementOOB(MachineInstr &MI, BuildFnTy &MatchInfo);

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,59 @@ class GFreeze : public GenericMachineInstr {
792792
}
793793
};
794794

795+
/// Represents a cast operation.
796+
/// It models the llvm::CastInst concept.
797+
/// The exception is bitcast.
798+
class GCastOp : public GenericMachineInstr {
799+
public:
800+
Register getSrcReg() const { return getOperand(1).getReg(); }
801+
802+
static bool classof(const MachineInstr *MI) {
803+
switch (MI->getOpcode()) {
804+
case TargetOpcode::G_ADDRSPACE_CAST:
805+
case TargetOpcode::G_FPEXT:
806+
case TargetOpcode::G_FPTOSI:
807+
case TargetOpcode::G_FPTOUI:
808+
case TargetOpcode::G_FPTRUNC:
809+
case TargetOpcode::G_INTTOPTR:
810+
case TargetOpcode::G_PTRTOINT:
811+
case TargetOpcode::G_SEXT:
812+
case TargetOpcode::G_SITOFP:
813+
case TargetOpcode::G_TRUNC:
814+
case TargetOpcode::G_UITOFP:
815+
case TargetOpcode::G_ZEXT:
816+
case TargetOpcode::G_ANYEXT:
817+
return true;
818+
default:
819+
return false;
820+
}
821+
};
822+
};
823+
824+
/// Represents a sext.
825+
class GSext : public GCastOp {
826+
public:
827+
static bool classof(const MachineInstr *MI) {
828+
return MI->getOpcode() == TargetOpcode::G_SEXT;
829+
};
830+
};
831+
832+
/// Represents a zext.
833+
class GZext : public GCastOp {
834+
public:
835+
static bool classof(const MachineInstr *MI) {
836+
return MI->getOpcode() == TargetOpcode::G_ZEXT;
837+
};
838+
};
839+
840+
/// Represents a trunc.
841+
class GTrunc : public GCastOp {
842+
public:
843+
static bool classof(const MachineInstr *MI) {
844+
return MI->getOpcode() == TargetOpcode::G_TRUNC;
845+
};
846+
};
847+
795848
} // namespace llvm
796849

797850
#endif // LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,8 @@ class MachineIRBuilder {
746746
/// \pre \p Op must be smaller than \p Res
747747
///
748748
/// \return The newly created instruction.
749-
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op);
749+
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op,
750+
std::optional<unsigned> Flags = std::nullopt);
750751

751752
/// Build and insert \p Res = G_SEXT \p Op, \p Res = G_TRUNC \p Op, or
752753
/// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
@@ -1231,7 +1232,8 @@ class MachineIRBuilder {
12311232
/// \pre \p Res must be smaller than \p Op
12321233
///
12331234
/// \return The newly created instruction.
1234-
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op);
1235+
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op,
1236+
std::optional<unsigned> Flags = std::nullopt);
12351237

12361238
/// Build and insert a \p Res = G_ICMP \p Pred, \p Op0, \p Op1
12371239
///

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ def FmContract : MIFlagEnum<"FmContract">;
180180
def FmAfn : MIFlagEnum<"FmAfn">;
181181
def FmReassoc : MIFlagEnum<"FmReassoc">;
182182
def IsExact : MIFlagEnum<"IsExact">;
183+
def NoSWrap : MIFlagEnum<"NoSWrap">;
184+
def NoUWrap : MIFlagEnum<"NoUWrap">;
183185

184186
def MIFlags;
185187
// def not; -> Already defined as a SDNode
@@ -1501,6 +1503,20 @@ def extract_vector_element_freeze : GICombineRule<
15011503
[{ return Helper.matchExtractVectorElementWithFreeze(${root}, ${matchinfo}); }]),
15021504
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
15031505

1506+
def sext_trunc : GICombineRule<
1507+
(defs root:$root, build_fn_matchinfo:$matchinfo),
1508+
(match (G_TRUNC $src, $x, (MIFlags NoSWrap)),
1509+
(G_SEXT $root, $src),
1510+
[{ return Helper.matchSextOfTrunc(${root}, ${matchinfo}); }]),
1511+
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
1512+
1513+
def zext_trunc : GICombineRule<
1514+
(defs root:$root, build_fn_matchinfo:$matchinfo),
1515+
(match (G_TRUNC $src, $x, (MIFlags NoUWrap)),
1516+
(G_ZEXT $root, $src),
1517+
[{ return Helper.matchZextOfTrunc(${root}, ${matchinfo}); }]),
1518+
(apply [{ Helper.applyBuildFnMO(${root}, ${matchinfo}); }])>;
1519+
15041520
def extract_vector_element_shuffle_vector : GICombineRule<
15051521
(defs root:$root, build_fn_matchinfo:$matchinfo),
15061522
(match (G_SHUFFLE_VECTOR $src, $src1, $src2, $mask),
@@ -1666,7 +1682,7 @@ def all_combines : GICombineGroup<[trivial_combines, vector_ops_combines,
16661682
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
16671683
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
16681684
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
1669-
combine_shuffle_concat]>;
1685+
sext_trunc, zext_trunc, combine_shuffle_concat]>;
16701686

16711687
// A combine group used to for prelegalizer combiners at -O0. The combines in
16721688
// this group have been selected based on experiments to balance code size and

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4137,14 +4137,6 @@ void CombinerHelper::applyBuildFn(
41374137
MI.eraseFromParent();
41384138
}
41394139

4140-
void CombinerHelper::applyBuildFnMO(const MachineOperand &MO,
4141-
BuildFnTy &MatchInfo) {
4142-
MachineInstr *Root = getDefIgnoringCopies(MO.getReg(), MRI);
4143-
Builder.setInstrAndDebugLoc(*Root);
4144-
MatchInfo(Builder);
4145-
Root->eraseFromParent();
4146-
}
4147-
41484140
void CombinerHelper::applyBuildFnNoErase(
41494141
MachineInstr &MI, std::function<void(MachineIRBuilder &)> &MatchInfo) {
41504142
MatchInfo(Builder);
@@ -7252,3 +7244,78 @@ bool CombinerHelper::matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) {
72527244

72537245
return false;
72547246
}
7247+
7248+
void CombinerHelper::applyBuildFnMO(const MachineOperand &MO,
7249+
BuildFnTy &MatchInfo) {
7250+
MachineInstr *Root = getDefIgnoringCopies(MO.getReg(), MRI);
7251+
MatchInfo(Builder);
7252+
Root->eraseFromParent();
7253+
}
7254+
7255+
bool CombinerHelper::matchSextOfTrunc(const MachineOperand &MO,
7256+
BuildFnTy &MatchInfo) {
7257+
GSext *Sext = cast<GSext>(getDefIgnoringCopies(MO.getReg(), MRI));
7258+
GTrunc *Trunc = cast<GTrunc>(getDefIgnoringCopies(Sext->getSrcReg(), MRI));
7259+
7260+
Register Dst = Sext->getReg(0);
7261+
Register Src = Trunc->getSrcReg();
7262+
7263+
LLT DstTy = MRI.getType(Dst);
7264+
LLT SrcTy = MRI.getType(Src);
7265+
7266+
if (DstTy == SrcTy) {
7267+
MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, Src); };
7268+
return true;
7269+
}
7270+
7271+
if (DstTy.getScalarSizeInBits() < SrcTy.getScalarSizeInBits() &&
7272+
isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {DstTy, SrcTy}})) {
7273+
MatchInfo = [=](MachineIRBuilder &B) {
7274+
B.buildTrunc(Dst, Src, MachineInstr::MIFlag::NoSWrap);
7275+
};
7276+
return true;
7277+
}
7278+
7279+
if (DstTy.getScalarSizeInBits() > SrcTy.getScalarSizeInBits() &&
7280+
isLegalOrBeforeLegalizer({TargetOpcode::G_SEXT, {DstTy, SrcTy}})) {
7281+
MatchInfo = [=](MachineIRBuilder &B) { B.buildSExt(Dst, Src); };
7282+
return true;
7283+
}
7284+
7285+
return false;
7286+
}
7287+
7288+
bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
7289+
BuildFnTy &MatchInfo) {
7290+
GZext *Zext = cast<GZext>(getDefIgnoringCopies(MO.getReg(), MRI));
7291+
GTrunc *Trunc = cast<GTrunc>(getDefIgnoringCopies(Zext->getSrcReg(), MRI));
7292+
7293+
Register Dst = Zext->getReg(0);
7294+
Register Src = Trunc->getSrcReg();
7295+
7296+
LLT DstTy = MRI.getType(Dst);
7297+
LLT SrcTy = MRI.getType(Src);
7298+
7299+
if (DstTy == SrcTy) {
7300+
MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(Dst, Src); };
7301+
return true;
7302+
}
7303+
7304+
if (DstTy.getScalarSizeInBits() < SrcTy.getScalarSizeInBits() &&
7305+
isLegalOrBeforeLegalizer({TargetOpcode::G_TRUNC, {DstTy, SrcTy}})) {
7306+
MatchInfo = [=](MachineIRBuilder &B) {
7307+
B.buildTrunc(Dst, Src, MachineInstr::MIFlag::NoUWrap);
7308+
};
7309+
return true;
7310+
}
7311+
7312+
if (DstTy.getScalarSizeInBits() > SrcTy.getScalarSizeInBits() &&
7313+
isLegalOrBeforeLegalizer({TargetOpcode::G_ZEXT, {DstTy, SrcTy}})) {
7314+
MatchInfo = [=](MachineIRBuilder &B) {
7315+
B.buildZExt(Dst, Src, MachineInstr::MIFlag::NonNeg);
7316+
};
7317+
return true;
7318+
}
7319+
7320+
return false;
7321+
}

llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ KnownBits GISelKnownBits::getKnownBits(MachineInstr &MI) {
6464

6565
KnownBits GISelKnownBits::getKnownBits(Register R) {
6666
const LLT Ty = MRI.getType(R);
67+
// Since the number of lanes in a scalable vector is unknown at compile time,
68+
// we track one bit which is implicitly broadcast to all lanes. This means
69+
// that all lanes in a scalable vector are considered demanded.
6770
APInt DemandedElts =
68-
Ty.isVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
71+
Ty.isFixedVector() ? APInt::getAllOnes(Ty.getNumElements()) : APInt(1, 1);
6972
return getKnownBits(R, DemandedElts);
7073
}
7174

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,9 @@ MachineInstrBuilder MachineIRBuilder::buildSExt(const DstOp &Res,
490490
}
491491

492492
MachineInstrBuilder MachineIRBuilder::buildZExt(const DstOp &Res,
493-
const SrcOp &Op) {
494-
return buildInstr(TargetOpcode::G_ZEXT, Res, Op);
493+
const SrcOp &Op,
494+
std::optional<unsigned> Flags) {
495+
return buildInstr(TargetOpcode::G_ZEXT, Res, Op, Flags);
495496
}
496497

497498
unsigned MachineIRBuilder::getBoolExtOp(bool IsVec, bool IsFP) const {
@@ -869,9 +870,10 @@ MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
869870
return buildIntrinsic(ID, Results, HasSideEffects, isConvergent);
870871
}
871872

872-
MachineInstrBuilder MachineIRBuilder::buildTrunc(const DstOp &Res,
873-
const SrcOp &Op) {
874-
return buildInstr(TargetOpcode::G_TRUNC, Res, Op);
873+
MachineInstrBuilder
874+
MachineIRBuilder::buildTrunc(const DstOp &Res, const SrcOp &Op,
875+
std::optional<unsigned> Flags) {
876+
return buildInstr(TargetOpcode::G_TRUNC, Res, Op, Flags);
875877
}
876878

877879
MachineInstrBuilder

0 commit comments

Comments
 (0)