[llvm] [GlobalISel] [AArch64] Skip redundant shift amount masking during isel (PR #223136)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 00:49:39 PDT 2026
================
@@ -7305,6 +7303,45 @@ AArch64InstructionSelector::selectShiftB_64(const MachineOperand &Root) const {
return {{[=](MachineInstrBuilder &MIB) { MIB.addImm(Enc); }}};
}
+template <unsigned ShiftWidth>
+InstructionSelector::ComplexRendererFns
+AArch64InstructionSelector::selectShiftMask(MachineOperand &Root) const {
+ if (!Root.isReg())
+ return std::nullopt;
+
+ MachineRegisterInfo &MRI =
+ Root.getParent()->getParent()->getParent()->getRegInfo();
+
+ Register ShAmtReg = Root.getReg();
+
+ // Peek through zext for i32 shifts only. For i64 shifts the zext case
+ // is already handled by existing patterns in the Shift multiclass.
+ if (ShiftWidth == 32) {
+ Register ZExtSrcReg;
+ if (mi_match(ShAmtReg, MRI, m_GZExt(m_Reg(ZExtSrcReg))))
+ ShAmtReg = ZExtSrcReg;
+ }
+
+ // Remove redundant AND mask that exactly covers a narrow type (byte,
+ // halfword, word) and whose result type matches the shift width. This
+ // avoids removing intentional masks used in fshl/fshr computations.
+ APInt AndMask;
+ Register AndSrcReg;
+ if (mi_match(ShAmtReg, MRI, m_GAnd(m_Reg(AndSrcReg), m_ICst(AndMask))) &&
+ MRI.getType(ShAmtReg).getSizeInBits() == ShiftWidth) {
+ uint64_t UMask = AndMask.getZExtValue();
+ if (UMask == 0xff || UMask == 0xffff || UMask == 0xffffffff)
----------------
davemgreen wrote:
Mask.countr_one() > ShiftWidth
https://github.com/llvm/llvm-project/pull/223136
More information about the llvm-commits
mailing list