@@ -5618,55 +5618,96 @@ SDValue SystemZTargetLowering::combineBSWAP(
5618
5618
static bool combineCCMask (SDValue &CCReg, int &CCValid, int &CCMask) {
5619
5619
// We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
5620
5620
// set by the CCReg instruction using the CCValid / CCMask masks,
5621
- // If the CCReg instruction is itself a (ICMP (SELECT_CCMASK)) testing
5622
- // the condition code set by some other instruction, see whether we
5623
- // can directly use that condition code.
5624
- bool Invert = false ;
5621
+ // If the CCReg instruction is itself a ICMP testing the condition
5622
+ // code set by some other instruction, see whether we can directly
5623
+ // use that condition code.
5625
5624
5626
- // Verify that we have an appropriate mask for a EQ or NE comparison .
5625
+ // Verify that we have an ICMP against some constant .
5627
5626
if (CCValid != SystemZ::CCMASK_ICMP)
5628
5627
return false ;
5629
- if (CCMask == SystemZ::CCMASK_CMP_NE)
5630
- Invert = !Invert;
5631
- else if (CCMask != SystemZ::CCMASK_CMP_EQ)
5632
- return false ;
5633
-
5634
- // Verify that we have an ICMP that is the user of a SELECT_CCMASK.
5635
- SDNode *ICmp = CCReg.getNode ();
5628
+ auto *ICmp = CCReg.getNode ();
5636
5629
if (ICmp->getOpcode () != SystemZISD::ICMP)
5637
5630
return false ;
5638
- SDNode *Select = ICmp->getOperand (0 ).getNode ();
5639
- if (Select->getOpcode () != SystemZISD::SELECT_CCMASK)
5631
+ auto *CompareLHS = ICmp->getOperand (0 ).getNode ();
5632
+ auto *CompareRHS = dyn_cast<ConstantSDNode>(ICmp->getOperand (1 ));
5633
+ if (!CompareRHS)
5640
5634
return false ;
5641
5635
5642
- // Verify that the ICMP compares against one of select values.
5643
- auto *CompareVal = dyn_cast<ConstantSDNode>(ICmp->getOperand (1 ));
5644
- if (!CompareVal)
5645
- return false ;
5646
- auto *TrueVal = dyn_cast<ConstantSDNode>(Select->getOperand (0 ));
5647
- if (!TrueVal)
5648
- return false ;
5649
- auto *FalseVal = dyn_cast<ConstantSDNode>(Select->getOperand (1 ));
5650
- if (!FalseVal)
5651
- return false ;
5652
- if (CompareVal->getZExtValue () == FalseVal->getZExtValue ())
5653
- Invert = !Invert;
5654
- else if (CompareVal->getZExtValue () != TrueVal->getZExtValue ())
5655
- return false ;
5636
+ // Optimize the case where CompareLHS is a SELECT_CCMASK.
5637
+ if (CompareLHS->getOpcode () == SystemZISD::SELECT_CCMASK) {
5638
+ // Verify that we have an appropriate mask for a EQ or NE comparison.
5639
+ bool Invert = false ;
5640
+ if (CCMask == SystemZ::CCMASK_CMP_NE)
5641
+ Invert = !Invert;
5642
+ else if (CCMask != SystemZ::CCMASK_CMP_EQ)
5643
+ return false ;
5656
5644
5657
- // Compute the effective CC mask for the new branch or select.
5658
- auto *NewCCValid = dyn_cast<ConstantSDNode>(Select->getOperand (2 ));
5659
- auto *NewCCMask = dyn_cast<ConstantSDNode>(Select->getOperand (3 ));
5660
- if (!NewCCValid || !NewCCMask)
5661
- return false ;
5662
- CCValid = NewCCValid->getZExtValue ();
5663
- CCMask = NewCCMask->getZExtValue ();
5664
- if (Invert)
5665
- CCMask ^= CCValid;
5645
+ // Verify that the ICMP compares against one of select values.
5646
+ auto *TrueVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand (0 ));
5647
+ if (!TrueVal)
5648
+ return false ;
5649
+ auto *FalseVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand (1 ));
5650
+ if (!FalseVal)
5651
+ return false ;
5652
+ if (CompareRHS->getZExtValue () == FalseVal->getZExtValue ())
5653
+ Invert = !Invert;
5654
+ else if (CompareRHS->getZExtValue () != TrueVal->getZExtValue ())
5655
+ return false ;
5666
5656
5667
- // Return the updated CCReg link.
5668
- CCReg = Select->getOperand (4 );
5669
- return true ;
5657
+ // Compute the effective CC mask for the new branch or select.
5658
+ auto *NewCCValid = dyn_cast<ConstantSDNode>(CompareLHS->getOperand (2 ));
5659
+ auto *NewCCMask = dyn_cast<ConstantSDNode>(CompareLHS->getOperand (3 ));
5660
+ if (!NewCCValid || !NewCCMask)
5661
+ return false ;
5662
+ CCValid = NewCCValid->getZExtValue ();
5663
+ CCMask = NewCCMask->getZExtValue ();
5664
+ if (Invert)
5665
+ CCMask ^= CCValid;
5666
+
5667
+ // Return the updated CCReg link.
5668
+ CCReg = CompareLHS->getOperand (4 );
5669
+ return true ;
5670
+ }
5671
+
5672
+ // Optimize the case where CompareRHS is (SRA (SHL (IPM))).
5673
+ if (CompareLHS->getOpcode () == ISD::SRA) {
5674
+ auto *SRACount = dyn_cast<ConstantSDNode>(CompareLHS->getOperand (1 ));
5675
+ if (!SRACount || SRACount->getZExtValue () != 30 )
5676
+ return false ;
5677
+ auto *SHL = CompareLHS->getOperand (0 ).getNode ();
5678
+ if (SHL->getOpcode () != ISD::SHL)
5679
+ return false ;
5680
+ auto *SHLCount = dyn_cast<ConstantSDNode>(SHL->getOperand (1 ));
5681
+ if (!SHLCount || SHLCount->getZExtValue () != 30 - SystemZ::IPM_CC)
5682
+ return false ;
5683
+ auto *IPM = SHL->getOperand (0 ).getNode ();
5684
+ if (IPM->getOpcode () != SystemZISD::IPM)
5685
+ return false ;
5686
+
5687
+ // Avoid introducing CC spills (because SRA would clobber CC).
5688
+ if (!CompareLHS->hasOneUse ())
5689
+ return false ;
5690
+ // Verify that the ICMP compares against zero.
5691
+ if (CompareRHS->getZExtValue () != 0 )
5692
+ return false ;
5693
+
5694
+ // Compute the effective CC mask for the new branch or select.
5695
+ switch (CCMask) {
5696
+ case SystemZ::CCMASK_CMP_EQ: break ;
5697
+ case SystemZ::CCMASK_CMP_NE: break ;
5698
+ case SystemZ::CCMASK_CMP_LT: CCMask = SystemZ::CCMASK_CMP_GT; break ;
5699
+ case SystemZ::CCMASK_CMP_GT: CCMask = SystemZ::CCMASK_CMP_LT; break ;
5700
+ case SystemZ::CCMASK_CMP_LE: CCMask = SystemZ::CCMASK_CMP_GE; break ;
5701
+ case SystemZ::CCMASK_CMP_GE: CCMask = SystemZ::CCMASK_CMP_LE; break ;
5702
+ default : return false ;
5703
+ }
5704
+
5705
+ // Return the updated CCReg link.
5706
+ CCReg = IPM->getOperand (0 );
5707
+ return true ;
5708
+ }
5709
+
5710
+ return false ;
5670
5711
}
5671
5712
5672
5713
SDValue SystemZTargetLowering::combineBR_CCMASK (
0 commit comments