@@ -50,6 +50,11 @@ struct FoldCandidate {
50
50
}
51
51
}
52
52
53
+ FoldCandidate (MachineInstr *MI, unsigned OpNo, int64_t FoldImm,
54
+ bool Commuted_ = false , int ShrinkOp = -1 )
55
+ : UseMI(MI), ImmToFold(FoldImm), ShrinkOpcode(ShrinkOp), UseOpNo(OpNo),
56
+ Kind(MachineOperand::MO_Immediate), Commuted(Commuted_) {}
57
+
53
58
bool isFI () const {
54
59
return Kind == MachineOperand::MO_FrameIndex;
55
60
}
@@ -578,16 +583,29 @@ bool SIFoldOperandsImpl::updateOperand(FoldCandidate &Fold) const {
578
583
}
579
584
580
585
static void appendFoldCandidate (SmallVectorImpl<FoldCandidate> &FoldList,
581
- MachineInstr *MI, unsigned OpNo,
582
- MachineOperand *FoldOp, bool Commuted = false ,
583
- int ShrinkOp = -1 ) {
586
+ FoldCandidate &&Entry) {
584
587
// Skip additional folding on the same operand.
585
588
for (FoldCandidate &Fold : FoldList)
586
- if (Fold.UseMI == MI && Fold.UseOpNo == OpNo )
589
+ if (Fold.UseMI == Entry. UseMI && Fold.UseOpNo == Entry. UseOpNo )
587
590
return ;
588
- LLVM_DEBUG (dbgs () << " Append " << (Commuted ? " commuted" : " normal" )
589
- << " operand " << OpNo << " \n " << *MI);
590
- FoldList.emplace_back (MI, OpNo, FoldOp, Commuted, ShrinkOp);
591
+ LLVM_DEBUG (dbgs () << " Append " << (Entry.Commuted ? " commuted" : " normal" )
592
+ << " operand " << Entry.UseOpNo << " \n " << *Entry.UseMI );
593
+ FoldList.push_back (Entry);
594
+ }
595
+
596
+ static void appendFoldCandidate (SmallVectorImpl<FoldCandidate> &FoldList,
597
+ MachineInstr *MI, unsigned OpNo,
598
+ MachineOperand *FoldOp, bool Commuted = false ,
599
+ int ShrinkOp = -1 ) {
600
+ appendFoldCandidate (FoldList,
601
+ FoldCandidate (MI, OpNo, FoldOp, Commuted, ShrinkOp));
602
+ }
603
+
604
+ static void appendFoldCandidate (SmallVectorImpl<FoldCandidate> &FoldList,
605
+ MachineInstr *MI, unsigned OpNo, int64_t ImmVal,
606
+ bool Commuted = false , int ShrinkOp = -1 ) {
607
+ appendFoldCandidate (FoldList,
608
+ FoldCandidate (MI, OpNo, ImmVal, Commuted, ShrinkOp));
591
609
}
592
610
593
611
bool SIFoldOperandsImpl::tryAddToFoldList (
@@ -847,11 +865,35 @@ bool SIFoldOperandsImpl::tryToFoldACImm(
847
865
return false ;
848
866
849
867
uint8_t OpTy = Desc.operands ()[UseOpIdx].OperandType ;
850
- if (OpToFold.isImm () && TII->isOperandLegal (*UseMI, UseOpIdx, &OpToFold)) {
851
- appendFoldCandidate (FoldList, UseMI, UseOpIdx, &OpToFold);
852
- return true ;
868
+ MachineOperand &UseOp = UseMI->getOperand (UseOpIdx);
869
+ if (OpToFold.isImm ()) {
870
+ if (unsigned UseSubReg = UseOp.getSubReg ()) {
871
+ std::optional<int64_t > SubImm =
872
+ SIInstrInfo::extractSubregFromImm (OpToFold.getImm (), UseSubReg);
873
+ if (!SubImm)
874
+ return false ;
875
+
876
+ // TODO: Avoid the temporary MachineOperand
877
+ MachineOperand TmpOp = MachineOperand::CreateImm (*SubImm);
878
+ if (TII->isOperandLegal (*UseMI, UseOpIdx, &TmpOp)) {
879
+ appendFoldCandidate (FoldList, UseMI, UseOpIdx, *SubImm);
880
+ return true ;
881
+ }
882
+
883
+ return false ;
884
+ }
885
+
886
+ if (TII->isOperandLegal (*UseMI, UseOpIdx, &OpToFold)) {
887
+ appendFoldCandidate (FoldList, UseMI, UseOpIdx, &OpToFold);
888
+ return true ;
889
+ }
853
890
}
854
891
892
+ // TODO: Verify the following code handles subregisters correctly.
893
+ // TODO: Handle extract of global reference
894
+ if (UseOp.getSubReg ())
895
+ return false ;
896
+
855
897
if (!OpToFold.isReg ())
856
898
return false ;
857
899
@@ -861,8 +903,7 @@ bool SIFoldOperandsImpl::tryToFoldACImm(
861
903
862
904
// Maybe it is just a COPY of an immediate itself.
863
905
MachineInstr *Def = MRI->getVRegDef (UseReg);
864
- MachineOperand &UseOp = UseMI->getOperand (UseOpIdx);
865
- if (!UseOp.getSubReg () && Def && TII->isFoldableCopy (*Def)) {
906
+ if (Def && TII->isFoldableCopy (*Def)) {
866
907
MachineOperand &DefOp = Def->getOperand (1 );
867
908
if (DefOp.isImm () && TII->isOperandLegal (*UseMI, UseOpIdx, &DefOp)) {
868
909
appendFoldCandidate (FoldList, UseMI, UseOpIdx, &DefOp);
0 commit comments