@@ -80,10 +80,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
80
80
setOperationAction (ISD::SIGN_EXTEND_INREG, VT, Expand);
81
81
82
82
if (Subtarget.is64Bit ()) {
83
- setTargetDAGCombine (ISD::SHL);
84
- setTargetDAGCombine (ISD::SRL);
85
- setTargetDAGCombine (ISD::SRA);
86
83
setTargetDAGCombine (ISD::ANY_EXTEND);
84
+ setOperationAction (ISD::SHL, MVT::i32, Custom);
85
+ setOperationAction (ISD::SRA, MVT::i32, Custom);
86
+ setOperationAction (ISD::SRL, MVT::i32, Custom);
87
87
}
88
88
89
89
if (!Subtarget.hasStdExtM ()) {
@@ -512,15 +512,52 @@ SDValue RISCVTargetLowering::lowerRETURNADDR(SDValue Op,
512
512
return DAG.getCopyFromReg (DAG.getEntryNode (), DL, Reg, XLenVT);
513
513
}
514
514
515
- // Return true if the given node is a shift with a non-constant shift amount.
516
- static bool isVariableShift (SDValue Val) {
517
- switch (Val.getOpcode ()) {
515
+ // Returns the opcode of the target-specific SDNode that implements the 32-bit
516
+ // form of the given Opcode.
517
+ static RISCVISD::NodeType getRISCVWOpcode (unsigned Opcode) {
518
+ switch (Opcode) {
518
519
default :
519
- return false ;
520
+ llvm_unreachable ( " Unexpected opcode " ) ;
520
521
case ISD::SHL:
522
+ return RISCVISD::SLLW;
521
523
case ISD::SRA:
524
+ return RISCVISD::SRAW;
522
525
case ISD::SRL:
523
- return Val.getOperand (1 ).getOpcode () != ISD::Constant;
526
+ return RISCVISD::SRLW;
527
+ }
528
+ }
529
+
530
+ // Converts the given 32-bit operation to a target-specific SelectionDAG node.
531
+ // Because i32 isn't a legal type for RV64, these operations would otherwise
532
+ // be promoted to i64, making it difficult to select the SLLW/DIVUW/.../*W
533
+ // later one because the fact the operation was originally of type i32 is
534
+ // lost.
535
+ static SDValue customLegalizeToWOp (SDNode *N, SelectionDAG &DAG) {
536
+ SDLoc DL (N);
537
+ RISCVISD::NodeType WOpcode = getRISCVWOpcode (N->getOpcode ());
538
+ SDValue NewOp0 = DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand (0 ));
539
+ SDValue NewOp1 = DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand (1 ));
540
+ SDValue NewRes = DAG.getNode (WOpcode, DL, MVT::i64, NewOp0, NewOp1);
541
+ // ReplaceNodeResults requires we maintain the same type for the return value.
542
+ return DAG.getNode (ISD::TRUNCATE, DL, MVT::i32, NewRes);
543
+ }
544
+
545
+ void RISCVTargetLowering::ReplaceNodeResults (SDNode *N,
546
+ SmallVectorImpl<SDValue> &Results,
547
+ SelectionDAG &DAG) const {
548
+ SDLoc DL (N);
549
+ switch (N->getOpcode ()) {
550
+ default :
551
+ llvm_unreachable (" Don't know how to custom type legalize this operation!" );
552
+ case ISD::SHL:
553
+ case ISD::SRA:
554
+ case ISD::SRL:
555
+ assert (N->getValueType (0 ) == MVT::i32 && Subtarget.is64Bit () &&
556
+ " Unexpected custom legalisation" );
557
+ if (N->getOperand (1 ).getOpcode () == ISD::Constant)
558
+ return ;
559
+ Results.push_back (customLegalizeToWOp (N, DAG));
560
+ break ;
524
561
}
525
562
}
526
563
@@ -545,34 +582,14 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
545
582
switch (N->getOpcode ()) {
546
583
default :
547
584
break ;
548
- case ISD::SHL:
549
- case ISD::SRL:
550
- case ISD::SRA: {
551
- assert (Subtarget.getXLen () == 64 && " Combine should be 64-bit only" );
552
- if (!DCI.isBeforeLegalize ())
553
- break ;
554
- SDValue RHS = N->getOperand (1 );
555
- if (N->getValueType (0 ) != MVT::i32 || RHS->getOpcode () == ISD::Constant ||
556
- (RHS->getOpcode () == ISD::AssertZext &&
557
- cast<VTSDNode>(RHS->getOperand (1 ))->getVT ().getSizeInBits () <= 5 ))
558
- break ;
559
- SDValue LHS = N->getOperand (0 );
560
- SDLoc DL (N);
561
- SDValue NewRHS =
562
- DAG.getNode (ISD::AssertZext, DL, RHS.getValueType (), RHS,
563
- DAG.getValueType (EVT::getIntegerVT (*DAG.getContext (), 5 )));
564
- return DCI.CombineTo (
565
- N, DAG.getNode (N->getOpcode (), DL, LHS.getValueType (), LHS, NewRHS));
566
- }
567
585
case ISD::ANY_EXTEND: {
568
- // If any-extending an i32 variable-length shift or sdiv/udiv/urem to i64,
569
- // then instead sign-extend in order to increase the chance of being able
570
- // to select the sllw/srlw/sraw/ divw/divuw/remuw instructions.
586
+ // If any-extending an i32 sdiv/udiv/urem to i64, then instead sign-extend
587
+ // in order to increase the chance of being able to select the
588
+ // divw/divuw/remuw instructions.
571
589
SDValue Src = N->getOperand (0 );
572
590
if (N->getValueType (0 ) != MVT::i64 || Src.getValueType () != MVT::i32)
573
591
break ;
574
- if (!isVariableShift (Src) &&
575
- !(Subtarget.hasStdExtM () && isVariableSDivUDivURem (Src)))
592
+ if (!(Subtarget.hasStdExtM () && isVariableSDivUDivURem (Src)))
576
593
break ;
577
594
SDLoc DL (N);
578
595
// Don't add the new node to the DAGCombiner worklist, in order to avoid
@@ -589,11 +606,42 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
589
606
break ;
590
607
return DCI.CombineTo (N, Op0.getOperand (0 ), Op0.getOperand (1 ));
591
608
}
609
+ case RISCVISD::SLLW:
610
+ case RISCVISD::SRAW:
611
+ case RISCVISD::SRLW: {
612
+ // Only the lower 32 bits of LHS and lower 5 bits of RHS are read.
613
+ SDValue LHS = N->getOperand (0 );
614
+ SDValue RHS = N->getOperand (1 );
615
+ APInt LHSMask = APInt::getLowBitsSet (LHS.getValueSizeInBits (), 32 );
616
+ APInt RHSMask = APInt::getLowBitsSet (RHS.getValueSizeInBits (), 5 );
617
+ if ((SimplifyDemandedBits (N->getOperand (0 ), LHSMask, DCI)) ||
618
+ (SimplifyDemandedBits (N->getOperand (1 ), RHSMask, DCI)))
619
+ return SDValue ();
620
+ break ;
621
+ }
592
622
}
593
623
594
624
return SDValue ();
595
625
}
596
626
627
+ unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode (
628
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
629
+ unsigned Depth) const {
630
+ switch (Op.getOpcode ()) {
631
+ default :
632
+ break ;
633
+ case RISCVISD::SLLW:
634
+ case RISCVISD::SRAW:
635
+ case RISCVISD::SRLW:
636
+ // TODO: As the result is sign-extended, this is conservatively correct. A
637
+ // more precise answer could be calculated for SRAW depending on known
638
+ // bits in the shift amount.
639
+ return 33 ;
640
+ }
641
+
642
+ return 1 ;
643
+ }
644
+
597
645
static MachineBasicBlock *emitSplitF64Pseudo (MachineInstr &MI,
598
646
MachineBasicBlock *BB) {
599
647
assert (MI.getOpcode () == RISCV::SplitF64Pseudo && " Unexpected instruction" );
@@ -1682,6 +1730,12 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
1682
1730
return " RISCVISD::SplitF64" ;
1683
1731
case RISCVISD::TAIL:
1684
1732
return " RISCVISD::TAIL" ;
1733
+ case RISCVISD::SLLW:
1734
+ return " RISCVISD::SLLW" ;
1735
+ case RISCVISD::SRAW:
1736
+ return " RISCVISD::SRAW" ;
1737
+ case RISCVISD::SRLW:
1738
+ return " RISCVISD::SRLW" ;
1685
1739
}
1686
1740
return nullptr ;
1687
1741
}
0 commit comments