@@ -2779,6 +2779,39 @@ bool RISCVTTIImpl::isProfitableToSinkOperands(
2779
2779
Instruction *I, SmallVectorImpl<Use *> &Ops) const {
2780
2780
using namespace llvm ::PatternMatch;
2781
2781
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
+
2782
2815
if (!I->getType ()->isVectorTy () || !ST->hasVInstructions ())
2783
2816
return false ;
2784
2817
0 commit comments