================ @@ -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)) + return nullptr; + + for (User *U : ZextHigh->users()) { + Value *X, *Y; + if (!match(U, m_Or(m_Value(X), m_Value(Y)))) + continue; + + if (!isa<ZExtInst>(Y)) + std::swap(X, Y); + + const APInt *ZextLowShlAmt; + if (!match(X, m_Shl(m_Specific(Or1), m_APInt(ZextLowShlAmt))) || + !match(Y, m_Specific(ZextHigh)) || !DT.dominates(U, &Or)) + continue; + + // Make sure Low does not overlap with High and most significant bits of + // Low aren't shifted out and we can rotate shift LowHigh to HighLow. + if (ZextLowShlAmt->ult(HighSize) || ZextLowShlAmt->ugt(Width - LowSize) || + *ZextLowShlAmt + *ZextHighShlAmt != Width) ---------------- goldsteinn wrote:
Think you are missing negative test for this (also for non-dominating). 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