aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp10
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp48
2 files changed, 58 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 8c05931..d930ab2 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -68,6 +68,16 @@ const TargetLowering &CombinerHelper::getTargetLowering() const {
return *Builder.getMF().getSubtarget().getTargetLowering();
}
+const MachineFunction &CombinerHelper::getMachineFunction() const {
+ return Builder.getMF();
+}
+
+const DataLayout &CombinerHelper::getDataLayout() const {
+ return getMachineFunction().getDataLayout();
+}
+
+LLVMContext &CombinerHelper::getContext() const { return Builder.getContext(); }
+
/// \returns The little endian in-memory byte position of byte \p I in a
/// \p ByteWidth bytes wide type.
///
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
index d36685b..59295f7 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
@@ -161,3 +161,51 @@ bool CombinerHelper::matchTruncateOfExt(const MachineInstr &Root,
return false;
}
+
+bool CombinerHelper::isCastFree(unsigned Opcode, LLT ToTy, LLT FromTy) const {
+ const TargetLowering &TLI = getTargetLowering();
+ const DataLayout &DL = getDataLayout();
+ LLVMContext &Ctx = getContext();
+
+ switch (Opcode) {
+ case TargetOpcode::G_ANYEXT:
+ case TargetOpcode::G_ZEXT:
+ return TLI.isZExtFree(FromTy, ToTy, DL, Ctx);
+ case TargetOpcode::G_TRUNC:
+ return TLI.isTruncateFree(FromTy, ToTy, DL, Ctx);
+ default:
+ return false;
+ }
+}
+
+bool CombinerHelper::matchCastOfSelect(const MachineInstr &CastMI,
+ const MachineInstr &SelectMI,
+ BuildFnTy &MatchInfo) {
+ const GExtOrTruncOp *Cast = cast<GExtOrTruncOp>(&CastMI);
+ const GSelect *Select = cast<GSelect>(&SelectMI);
+
+ if (!MRI.hasOneNonDBGUse(Select->getReg(0)))
+ return false;
+
+ Register Dst = Cast->getReg(0);
+ LLT DstTy = MRI.getType(Dst);
+ LLT CondTy = MRI.getType(Select->getCondReg());
+ Register TrueReg = Select->getTrueReg();
+ Register FalseReg = Select->getFalseReg();
+ LLT SrcTy = MRI.getType(TrueReg);
+ Register Cond = Select->getCondReg();
+
+ if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SELECT, {DstTy, CondTy}}))
+ return false;
+
+ if (!isCastFree(Cast->getOpcode(), DstTy, SrcTy))
+ return false;
+
+ MatchInfo = [=](MachineIRBuilder &B) {
+ auto True = B.buildInstr(Cast->getOpcode(), {DstTy}, {TrueReg});
+ auto False = B.buildInstr(Cast->getOpcode(), {DstTy}, {FalseReg});
+ B.buildSelect(Dst, Cond, True, False);
+ };
+
+ return true;
+}