@@ -2779,6 +2779,39 @@ bool RISCVTTIImpl::isProfitableToSinkOperands(
27792779 Instruction *I, SmallVectorImpl<Use *> &Ops) const {
27802780 using namespace llvm ::PatternMatch;
27812781
2782+ if (I->isBitwiseLogicOp ()) {
2783+ if (!I->getType ()->isVectorTy ()) {
2784+ if (ST->hasStdExtZbb () || ST->hasStdExtZbkb ()) {
2785+ for (auto &Op : I->operands ()) {
2786+ // (and/or/xor X, (not Y)) -> (andn/orn/xnor X, Y)
2787+ if (match (Op.get (), m_Not (m_Value ()))) {
2788+ Ops.push_back (&Op);
2789+ return true ;
2790+ }
2791+ }
2792+ }
2793+ } else if (I->getOpcode () == Instruction::And && ST->hasStdExtZvkb ()) {
2794+ for (auto &Op : I->operands ()) {
2795+ // (and X, (not Y)) -> (vandn.vv X, Y)
2796+ if (match (Op.get (), m_Not (m_Value ()))) {
2797+ Ops.push_back (&Op);
2798+ return true ;
2799+ }
2800+ // (and X, (splat (not Y))) -> (vandn.vx X, Y)
2801+ if (match (Op.get (), m_Shuffle (m_InsertElt (m_Value (), m_Not (m_Value ()),
2802+ m_ZeroInt ()),
2803+ m_Value (), m_ZeroMask ()))) {
2804+ Use &InsertElt = cast<Instruction>(Op)->getOperandUse (0 );
2805+ Use &Not = cast<Instruction>(InsertElt)->getOperandUse (1 );
2806+ Ops.push_back (&Not);
2807+ Ops.push_back (&InsertElt);
2808+ Ops.push_back (&Op);
2809+ return true ;
2810+ }
2811+ }
2812+ }
2813+ }
2814+
27822815 if (!I->getType ()->isVectorTy () || !ST->hasVInstructions ())
27832816 return false ;
27842817
0 commit comments