[llvm] [RISCV][GISel] Add ISel supports for SHXADD from Zba extension (PR #67863)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 6 09:24:00 PDT 2023
================
@@ -105,6 +112,110 @@ RISCVInstructionSelector::selectShiftMask(MachineOperand &Root) const {
return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}};
}
+InstructionSelector::ComplexRendererFns
+RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root,
+ unsigned ShAmt) const {
+ using namespace llvm::MIPatternMatch;
+ MachineFunction &MF = *Root.getParent()->getParent()->getParent();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+
+ if (!Root.isReg())
+ return std::nullopt;
+ Register RootReg = Root.getReg();
+
+ const unsigned XLen = STI.getXLen();
+ APInt Mask, C2;
+ Register RegY;
+ std::optional<bool> LeftShift;
+ // (and (shl y, c2), mask)
+ if (mi_match(RootReg, MRI,
+ m_GAnd(m_GShl(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask))))
+ LeftShift = true;
+ // (and (lshr y, c2), mask)
+ else if (mi_match(RootReg, MRI,
+ m_GAnd(m_GLShr(m_Reg(RegY), m_ICst(C2)), m_ICst(Mask))))
+ LeftShift = false;
+
+ if (LeftShift.has_value()) {
+ if (*LeftShift)
+ Mask &= maskTrailingZeros<uint64_t>(C2.getLimitedValue());
+ else
+ Mask &= maskTrailingOnes<uint64_t>(XLen - C2.getLimitedValue());
+
+ if (Mask.isShiftedMask()) {
+ unsigned Leading = XLen - Mask.getActiveBits();
+ unsigned Trailing = Mask.countr_zero();
+ // Given (and (shl y, c2), mask) in which mask has no leading zeros and
+ // c3 trailing zeros. We can use an SRLI by c3 - c2 followed by a SHXADD.
+ if (*LeftShift && Leading == 0 && C2.ult(Trailing) && Trailing == ShAmt) {
+ Register DstReg =
+ MRI.createGenericVirtualRegister(MRI.getType(RootReg));
+ return {{[=](MachineInstrBuilder &MIB) {
+ MachineIRBuilder(*MIB.getInstr())
+ .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
+ .addImm(Trailing - C2.getLimitedValue());
+ MIB.addReg(DstReg);
+ }}};
+ }
+
+ // Given (and (lshr y, c2), mask) in which mask has c2 leading zeros and c3
+ // trailing zeros. We can use an SRLI by c2 + c3 followed by a SHXADD.
+ if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
+ Register DstReg =
+ MRI.createGenericVirtualRegister(MRI.getType(RootReg));
+ return {{[=](MachineInstrBuilder &MIB) {
+ MachineIRBuilder(*MIB.getInstr())
+ .buildInstr(RISCV::SRLI, {DstReg}, {RegY})
+ .addImm(Leading + Trailing);
+ MIB.addReg(DstReg);
+ }}};
+ }
+ }
+ }
+
+ LeftShift.reset();
+
+ // (shl (and y, mask), c2)
+ if (mi_match(RootReg, MRI,
+ m_GShl(m_OneNonDBGUse(m_GAnd(m_Reg(RegY), m_ICst(Mask))),
+ m_ICst(C2))))
+ LeftShift = true;
+ // (lshr (and y, mask), c2)
+ else if (mi_match(RootReg, MRI,
+ m_GLShr(m_OneNonDBGUse(m_GAnd(m_Reg(RegY), m_ICst(Mask))),
+ m_ICst(C2))))
+ LeftShift = false;
+
+ if (LeftShift.has_value())
+ if (Mask.isShiftedMask()) {
----------------
topperc wrote:
Can we merge this condition with the previous if?
https://github.com/llvm/llvm-project/pull/67863
More information about the llvm-commits
mailing list