@@ -187,11 +187,8 @@ static bool hasMemOffset(SDNode *N, unsigned &BaseOpIdx,
187
187
return false ;
188
188
}
189
189
190
- static SDNode *selectImm (SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
191
- int64_t Imm, const RISCVSubtarget &Subtarget) {
192
- RISCVMatInt::InstSeq Seq =
193
- RISCVMatInt::generateInstSeq (Imm, Subtarget.getFeatureBits ());
194
-
190
+ static SDNode *selectImmSeq (SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
191
+ RISCVMatInt::InstSeq &Seq) {
195
192
SDNode *Result = nullptr ;
196
193
SDValue SrcReg = CurDAG->getRegister (RISCV::X0, VT);
197
194
for (RISCVMatInt::Inst &Inst : Seq) {
@@ -219,6 +216,14 @@ static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
219
216
return Result;
220
217
}
221
218
219
+ static SDNode *selectImm (SelectionDAG *CurDAG, const SDLoc &DL, const MVT VT,
220
+ int64_t Imm, const RISCVSubtarget &Subtarget) {
221
+ RISCVMatInt::InstSeq Seq =
222
+ RISCVMatInt::generateInstSeq (Imm, Subtarget.getFeatureBits ());
223
+
224
+ return selectImmSeq (CurDAG, DL, VT, Seq);
225
+ }
226
+
222
227
static SDValue createTuple (SelectionDAG &CurDAG, ArrayRef<SDValue> Regs,
223
228
unsigned NF, RISCVII::VLMUL LMUL) {
224
229
static const unsigned M1TupleRegClassIDs[] = {
@@ -667,6 +672,24 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
667
672
if (isInt<12 >(Offset / 2 ) && isInt<12 >(Offset - Offset / 2 ))
668
673
break ;
669
674
675
+ RISCVMatInt::InstSeq Seq =
676
+ RISCVMatInt::generateInstSeq (Offset, Subtarget->getFeatureBits ());
677
+
678
+ Offset -= Lo12;
679
+ // Restore sign bits for RV32.
680
+ if (!Subtarget->is64Bit ())
681
+ Offset = SignExtend64<32 >(Offset);
682
+
683
+ // We can fold if the last operation is an ADDI or its an ADDIW that could
684
+ // be treated as an ADDI.
685
+ if (Seq.back ().Opc != RISCV::ADDI &&
686
+ !(Seq.back ().Opc == RISCV::ADDIW && isInt<32 >(Offset)))
687
+ break ;
688
+ assert (Seq.back ().Imm == Lo12 && " Expected immediate to match Lo12" );
689
+ // Drop the last operation.
690
+ Seq.pop_back ();
691
+ assert (!Seq.empty () && " Expected more instructions in sequence" );
692
+
670
693
bool AllPointerUses = true ;
671
694
for (auto UI = Node->use_begin (), UE = Node->use_end (); UI != UE; ++UI) {
672
695
SDNode *User = *UI;
@@ -695,13 +718,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
695
718
if (!AllPointerUses)
696
719
break ;
697
720
698
- Offset -= Lo12;
699
- // Restore sign bits for RV32.
700
- if (!Subtarget->is64Bit ())
701
- Offset = SignExtend64<32 >(Offset);
702
-
703
721
// Emit (ADDI (ADD X, Hi), Lo)
704
- SDNode *Imm = selectImm (CurDAG, DL, VT, Offset, *Subtarget );
722
+ SDNode *Imm = selectImmSeq (CurDAG, DL, VT, Seq );
705
723
SDNode *ADD = CurDAG->getMachineNode (RISCV::ADD, DL, VT,
706
724
Node->getOperand (0 ), SDValue (Imm, 0 ));
707
725
SDNode *ADDI =
0 commit comments