Skip to content

Commit 63c7775

Browse files
committed
First commit
1 parent b5df0e7 commit 63c7775

File tree

3 files changed

+70
-20
lines changed

3 files changed

+70
-20
lines changed

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,13 @@ class CombinerHelper {
115115

116116
public:
117117
CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
118-
bool IsPreLegalize,
119-
GISelKnownBits *KB = nullptr,
118+
bool IsPreLegalize, GISelKnownBits *KB = nullptr,
120119
MachineDominatorTree *MDT = nullptr,
121120
const LegalizerInfo *LI = nullptr);
122121

123-
GISelKnownBits *getKnownBits() const {
124-
return KB;
125-
}
122+
GISelKnownBits *getKnownBits() const { return KB; }
126123

127-
MachineIRBuilder &getBuilder() const {
128-
return Builder;
129-
}
124+
MachineIRBuilder &getBuilder() const { return Builder; }
130125

131126
const TargetLowering &getTargetLowering() const;
132127

@@ -150,8 +145,10 @@ class CombinerHelper {
150145
/// is a legal integer constant type on the target.
151146
bool isConstantLegalOrBeforeLegalizer(const LLT Ty) const;
152147

153-
/// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
154-
void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
148+
/// MachineRegisterInfo::replaceRegWith() and inform the observer of the
149+
/// changes
150+
void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg,
151+
Register ToReg) const;
155152

156153
/// Replace a single register operand with a new register and inform the
157154
/// observer of the changes.
@@ -482,12 +479,12 @@ class CombinerHelper {
482479
bool matchEqualDefs(const MachineOperand &MOP1,
483480
const MachineOperand &MOP2) const;
484481

485-
/// Return true if \p MOP is defined by a G_CONSTANT or splat with a value equal to
486-
/// \p C.
482+
/// Return true if \p MOP is defined by a G_CONSTANT or splat with a value
483+
/// equal to \p C.
487484
bool matchConstantOp(const MachineOperand &MOP, int64_t C) const;
488485

489-
/// Return true if \p MOP is defined by a G_FCONSTANT or splat with a value exactly
490-
/// equal to \p C.
486+
/// Return true if \p MOP is defined by a G_FCONSTANT or splat with a value
487+
/// exactly equal to \p C.
491488
bool matchConstantFPOp(const MachineOperand &MOP, double C) const;
492489

493490
/// @brief Checks if constant at \p ConstIdx is larger than \p MI 's bitwidth
@@ -841,7 +838,8 @@ class CombinerHelper {
841838
BuildFnTy &MatchInfo) const;
842839

843840
/// Match shifts greater or equal to the bitwidth of the operation.
844-
bool matchShiftsTooBig(MachineInstr &MI) const;
841+
bool matchShiftsTooBig(MachineInstr &MI,
842+
std::optional<int64_t> &MatchInfo) const;
845843

846844
/// Match constant LHS ops that should be commuted.
847845
bool matchCommuteConstantToRHS(MachineInstr &MI) const;

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,18 @@ def ptr_add_immed_chain : GICombineRule<
306306
[{ return Helper.matchPtrAddImmedChain(*${d}, ${matchinfo}); }]),
307307
(apply [{ Helper.applyPtrAddImmedChain(*${d}, ${matchinfo}); }])>;
308308

309+
def shift_result_matchdata : GIDefMatchData<"std::optional<int64_t>">;
309310
def shifts_too_big : GICombineRule<
310-
(defs root:$root),
311+
(defs root:$root, shift_result_matchdata:$matchinfo),
311312
(match (wip_match_opcode G_SHL, G_ASHR, G_LSHR):$root,
312-
[{ return Helper.matchShiftsTooBig(*${root}); }]),
313-
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
313+
[{ return Helper.matchShiftsTooBig(*${root}, ${matchinfo}); }]),
314+
(apply [{
315+
if (${matchinfo}) {
316+
Helper.replaceInstWithConstant(*${root}, *${matchinfo});
317+
} else {
318+
Helper.replaceInstWithUndef(*${root});
319+
}
320+
}])>;
314321

315322
// Fold shift (shift base x), y -> shift base, (x+y), if shifts are same
316323
def shift_immed_matchdata : GIDefMatchData<"RegisterImmPair">;

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "llvm/Support/Casting.h"
3636
#include "llvm/Support/DivisionByConstantInfo.h"
3737
#include "llvm/Support/ErrorHandling.h"
38+
#include "llvm/Support/KnownBits.h"
3839
#include "llvm/Support/MathExtras.h"
3940
#include "llvm/Target/TargetMachine.h"
4041
#include <cmath>
@@ -6590,12 +6591,56 @@ bool CombinerHelper::matchRedundantBinOpInEquality(MachineInstr &MI,
65906591
return CmpInst::isEquality(Pred) && Y.isValid();
65916592
}
65926593

6593-
bool CombinerHelper::matchShiftsTooBig(MachineInstr &MI) const {
6594+
static std::optional<unsigned>
6595+
getMaxUsefulShift(KnownBits ValueKB, unsigned Opcode,
6596+
std::optional<int64_t> &Result) {
6597+
assert(Opcode == TargetOpcode::G_SHL || Opcode == TargetOpcode::G_LSHR ||
6598+
Opcode == TargetOpcode::G_ASHR && "Expect G_SHL, G_LSHR or G_ASHR.");
6599+
auto SignificantBits = 0;
6600+
switch (Opcode) {
6601+
case TargetOpcode::G_SHL:
6602+
SignificantBits = ValueKB.countMinTrailingZeros();
6603+
Result = 0;
6604+
break;
6605+
case TargetOpcode::G_LSHR:
6606+
Result = 0;
6607+
SignificantBits = ValueKB.countMinLeadingZeros();
6608+
break;
6609+
case TargetOpcode::G_ASHR:
6610+
if (ValueKB.isNonNegative()) {
6611+
SignificantBits = ValueKB.countMinLeadingZeros();
6612+
Result = 0;
6613+
} else if (ValueKB.isNegative()) {
6614+
SignificantBits = ValueKB.countMinLeadingOnes();
6615+
Result = -1;
6616+
} else {
6617+
// Cannot determine shift result.
6618+
Result = std::nullopt;
6619+
return false;
6620+
}
6621+
break;
6622+
default:
6623+
break;
6624+
}
6625+
return ValueKB.getBitWidth() - SignificantBits;
6626+
}
6627+
6628+
bool CombinerHelper::matchShiftsTooBig(
6629+
MachineInstr &MI, std::optional<int64_t> &MatchInfo) const {
6630+
Register ShiftVal = MI.getOperand(1).getReg();
65946631
Register ShiftReg = MI.getOperand(2).getReg();
65956632
LLT ResTy = MRI.getType(MI.getOperand(0).getReg());
65966633
auto IsShiftTooBig = [&](const Constant *C) {
65976634
auto *CI = dyn_cast<ConstantInt>(C);
6598-
return CI && CI->uge(ResTy.getScalarSizeInBits());
6635+
if (!CI)
6636+
return false;
6637+
if (CI->uge(ResTy.getScalarSizeInBits())) {
6638+
MatchInfo = std::nullopt;
6639+
return true;
6640+
}
6641+
auto OptMaxUsefulShift = getMaxUsefulShift(KB->getKnownBits(ShiftVal),
6642+
MI.getOpcode(), MatchInfo);
6643+
return OptMaxUsefulShift && CI->uge(*OptMaxUsefulShift);
65996644
};
66006645
return matchUnaryPredicate(MRI, ShiftReg, IsShiftTooBig);
66016646
}

0 commit comments

Comments
 (0)