================ @@ -2840,6 +2841,60 @@ static Instruction *matchFunnelShift(Instruction &Or, InstCombinerImpl &IC) { return nullptr; FShiftArgs = {ShVal0, ShVal1, ShAmt}; + } else if (isa<ZExtInst>(Or0) || isa<ZExtInst>(Or1)) { + // If there are two 'or' instructions concat variables in opposite order: + // + // Slot1 and Slot2 are all zero bits. + // | Slot1 | Low | Slot2 | High | + // LowHigh = or (shl (zext Low), ZextLowShlAmt), (zext High) + // | Slot2 | High | Slot1 | Low | + // HighLow = or (shl (zext High), ZextHighShlAmt), (zext Low) + // + // the latter 'or' can be safely convert to + // -> HighLow = fshl LowHigh, LowHigh, ZextHighShlAmt + // if ZextLowShlAmt + ZextHighShlAmt == Width. + if (!isa<ZExtInst>(Or1)) + std::swap(Or0, Or1); + + Value *High, *ZextHigh, *Low; + const APInt *ZextHighShlAmt; + if (!match(Or0, + m_OneUse(m_Shl(m_Value(ZextHigh), m_APInt(ZextHighShlAmt))))) + return nullptr; + + if (!match(Or1, m_ZExt(m_Value(Low))) || + !match(ZextHigh, m_ZExt(m_Value(High)))) + return nullptr; + + unsigned HighSize = High->getType()->getScalarSizeInBits(); + unsigned LowSize = Low->getType()->getScalarSizeInBits(); + // Make sure High does not overlap with Low and most significant bits of + // High aren't shifted out. + if (ZextHighShlAmt->ult(LowSize) || ZextHighShlAmt->ugt(Width - HighSize)) ---------------- HaohaiWen wrote:
Done https://github.com/llvm/llvm-project/pull/68502 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits