@@ -111,27 +111,18 @@ class ARM64DAGToDAGISel : public SelectionDAGISel {
111
111
return SelectAddrModeUnscaled (N, 16 , Base, OffImm);
112
112
}
113
113
114
- bool SelectAddrModeRO8 (SDValue N, SDValue &Base, SDValue &Offset,
115
- SDValue &Imm) {
116
- return SelectAddrModeRO (N, 1 , Base, Offset, Imm);
114
+ template <int Width>
115
+ bool SelectAddrModeWRO (SDValue N, SDValue &Base, SDValue &Offset,
116
+ SDValue &SignExtend, SDValue &DoShift) {
117
+ return SelectAddrModeWRO (N, Width / 8 , Base, Offset, SignExtend, DoShift);
117
118
}
118
- bool SelectAddrModeRO16 (SDValue N, SDValue &Base, SDValue &Offset,
119
- SDValue &Imm) {
120
- return SelectAddrModeRO (N, 2 , Base, Offset, Imm);
121
- }
122
- bool SelectAddrModeRO32 (SDValue N, SDValue &Base, SDValue &Offset,
123
- SDValue &Imm) {
124
- return SelectAddrModeRO (N, 4 , Base, Offset, Imm);
125
- }
126
- bool SelectAddrModeRO64 (SDValue N, SDValue &Base, SDValue &Offset,
127
- SDValue &Imm) {
128
- return SelectAddrModeRO (N, 8 , Base, Offset, Imm);
129
- }
130
- bool SelectAddrModeRO128 (SDValue N, SDValue &Base, SDValue &Offset,
131
- SDValue &Imm) {
132
- return SelectAddrModeRO (N, 16 , Base, Offset, Imm);
119
+
120
+ template <int Width>
121
+ bool SelectAddrModeXRO (SDValue N, SDValue &Base, SDValue &Offset,
122
+ SDValue &SignExtend, SDValue &DoShift) {
123
+ return SelectAddrModeXRO (N, Width / 8 , Base, Offset, SignExtend, DoShift);
133
124
}
134
- bool SelectAddrModeNoIndex (SDValue N, SDValue &Val);
125
+
135
126
136
127
// / Form sequences of consecutive 64/128-bit registers for use in NEON
137
128
// / instructions making use of a vector-list (e.g. ldN, tbl). Vecs must have
@@ -179,11 +170,15 @@ class ARM64DAGToDAGISel : public SelectionDAGISel {
179
170
SDValue &OffImm);
180
171
bool SelectAddrModeUnscaled (SDValue N, unsigned Size , SDValue &Base,
181
172
SDValue &OffImm);
182
- bool SelectAddrModeRO (SDValue N, unsigned Size , SDValue &Base,
183
- SDValue &Offset, SDValue &Imm);
173
+ bool SelectAddrModeWRO (SDValue N, unsigned Size , SDValue &Base,
174
+ SDValue &Offset, SDValue &SignExtend,
175
+ SDValue &DoShift);
176
+ bool SelectAddrModeXRO (SDValue N, unsigned Size , SDValue &Base,
177
+ SDValue &Offset, SDValue &SignExtend,
178
+ SDValue &DoShift);
184
179
bool isWorthFolding (SDValue V) const ;
185
- bool SelectExtendedSHL (SDValue N, unsigned Size , SDValue &Offset ,
186
- SDValue &Imm );
180
+ bool SelectExtendedSHL (SDValue N, unsigned Size , bool WantExtend ,
181
+ SDValue &Offset, SDValue &SignExtend );
187
182
188
183
template <unsigned RegWidth>
189
184
bool SelectCVTFixedPosOperand (SDValue N, SDValue &FixedPos) {
@@ -219,14 +214,6 @@ static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc,
219
214
isIntImmediate (N->getOperand (1 ).getNode (), Imm);
220
215
}
221
216
222
- bool ARM64DAGToDAGISel::SelectAddrModeNoIndex (SDValue N, SDValue &Val) {
223
- EVT ValTy = N.getValueType ();
224
- if (ValTy != MVT::i64)
225
- return false ;
226
- Val = N;
227
- return true ;
228
- }
229
-
230
217
bool ARM64DAGToDAGISel::SelectInlineAsmMemoryOperand (
231
218
const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
232
219
assert (ConstraintCode == ' m' && " unexpected asm memory constraint" );
@@ -563,8 +550,8 @@ bool ARM64DAGToDAGISel::SelectArithExtendedRegister(SDValue N, SDValue &Reg,
563
550
// if we're folding a (sext i8), we need the RHS to be a GPR32, even though
564
551
// there might not be an actual 32-bit value in the program. We can
565
552
// (harmlessly) synthesize one by injected an EXTRACT_SUBREG here.
566
- if (Reg. getValueType () == MVT::i64 && Ext != ARM64_AM::UXTX &&
567
- Ext != ARM64_AM::SXTX ) {
553
+ assert (Ext != ARM64_AM::UXTX && Ext != ARM64_AM::SXTX);
554
+ if (Reg. getValueType () == MVT::i64 ) {
568
555
SDValue SubReg = CurDAG->getTargetConstant (ARM64::sub_32, MVT::i32);
569
556
MachineSDNode *Node = CurDAG->getMachineNode (
570
557
TargetOpcode::EXTRACT_SUBREG, SDLoc (N), MVT::i32, Reg, SubReg);
@@ -675,47 +662,44 @@ static SDValue Widen(SelectionDAG *CurDAG, SDValue N) {
675
662
return SDValue (Node, 0 );
676
663
}
677
664
678
- static SDValue WidenIfNeeded (SelectionDAG *CurDAG, SDValue N) {
679
- if (N.getValueType () == MVT::i32) {
680
- return Widen (CurDAG, N);
681
- }
682
-
683
- return N;
684
- }
685
-
686
665
// / \brief Check if the given SHL node (\p N), can be used to form an
687
666
// / extended register for an addressing mode.
688
667
bool ARM64DAGToDAGISel::SelectExtendedSHL (SDValue N, unsigned Size ,
689
- SDValue &Offset, SDValue &Imm) {
668
+ bool WantExtend, SDValue &Offset,
669
+ SDValue &SignExtend) {
690
670
assert (N.getOpcode () == ISD::SHL && " Invalid opcode." );
691
671
ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand (1 ));
692
- if (CSD && (CSD->getZExtValue () & 0x7 ) == CSD->getZExtValue ()) {
672
+ if (!CSD || (CSD->getZExtValue () & 0x7 ) != CSD->getZExtValue ())
673
+ return false ;
693
674
675
+ if (WantExtend) {
694
676
ARM64_AM::ShiftExtendType Ext = getExtendTypeForNode (N.getOperand (0 ), true );
695
- if (Ext == ARM64_AM::InvalidShiftExtend) {
696
- Ext = ARM64_AM::UXTX;
697
- Offset = WidenIfNeeded (CurDAG, N.getOperand (0 ));
698
- } else {
699
- Offset = WidenIfNeeded (CurDAG, N.getOperand (0 ).getOperand (0 ));
700
- }
701
-
702
- unsigned LegalShiftVal = Log2_32 (Size );
703
- unsigned ShiftVal = CSD->getZExtValue ();
704
-
705
- if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
677
+ if (Ext == ARM64_AM::InvalidShiftExtend)
706
678
return false ;
707
679
708
- Imm = CurDAG->getTargetConstant (
709
- ARM64_AM::getMemExtendImm (Ext, ShiftVal != 0 ), MVT::i32);
710
- if (isWorthFolding (N))
711
- return true ;
680
+ Offset = N.getOperand (0 ).getOperand (0 );
681
+ SignExtend = CurDAG->getTargetConstant (Ext == ARM64_AM::SXTW, MVT::i32);
682
+ } else {
683
+ Offset = N.getOperand (0 );
684
+ SignExtend = CurDAG->getTargetConstant (0 , MVT::i32);
712
685
}
686
+
687
+ unsigned LegalShiftVal = Log2_32 (Size );
688
+ unsigned ShiftVal = CSD->getZExtValue ();
689
+
690
+ if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
691
+ return false ;
692
+
693
+ if (isWorthFolding (N))
694
+ return true ;
695
+
713
696
return false ;
714
697
}
715
698
716
- bool ARM64DAGToDAGISel::SelectAddrModeRO (SDValue N, unsigned Size ,
699
+ bool ARM64DAGToDAGISel::SelectAddrModeWRO (SDValue N, unsigned Size ,
717
700
SDValue &Base, SDValue &Offset,
718
- SDValue &Imm) {
701
+ SDValue &SignExtend,
702
+ SDValue &DoShift) {
719
703
if (N.getOpcode () != ISD::ADD)
720
704
return false ;
721
705
SDValue LHS = N.getOperand (0 );
@@ -740,26 +724,30 @@ bool ARM64DAGToDAGISel::SelectAddrModeRO(SDValue N, unsigned Size,
740
724
741
725
// Try to match a shifted extend on the RHS.
742
726
if (IsExtendedRegisterWorthFolding && RHS.getOpcode () == ISD::SHL &&
743
- SelectExtendedSHL (RHS, Size , Offset, Imm )) {
727
+ SelectExtendedSHL (RHS, Size , true , Offset, SignExtend )) {
744
728
Base = LHS;
729
+ DoShift = CurDAG->getTargetConstant (true , MVT::i32);
745
730
return true ;
746
731
}
747
732
748
733
// Try to match a shifted extend on the LHS.
749
734
if (IsExtendedRegisterWorthFolding && LHS.getOpcode () == ISD::SHL &&
750
- SelectExtendedSHL (LHS, Size , Offset, Imm )) {
735
+ SelectExtendedSHL (LHS, Size , true , Offset, SignExtend )) {
751
736
Base = RHS;
737
+ DoShift = CurDAG->getTargetConstant (true , MVT::i32);
752
738
return true ;
753
739
}
754
740
755
- ARM64_AM::ShiftExtendType Ext = ARM64_AM::UXTX;
741
+ // There was no shift, whatever else we find.
742
+ DoShift = CurDAG->getTargetConstant (false , MVT::i32);
743
+
744
+ ARM64_AM::ShiftExtendType Ext = ARM64_AM::InvalidShiftExtend;
756
745
// Try to match an unshifted extend on the LHS.
757
746
if (IsExtendedRegisterWorthFolding &&
758
747
(Ext = getExtendTypeForNode (LHS, true )) != ARM64_AM::InvalidShiftExtend) {
759
748
Base = RHS;
760
- Offset = WidenIfNeeded (CurDAG, LHS.getOperand (0 ));
761
- Imm = CurDAG->getTargetConstant (ARM64_AM::getMemExtendImm (Ext, false ),
762
- MVT::i32);
749
+ Offset = LHS.getOperand (0 );
750
+ SignExtend = CurDAG->getTargetConstant (Ext == ARM64_AM::SXTW, MVT::i32);
763
751
if (isWorthFolding (LHS))
764
752
return true ;
765
753
}
@@ -768,19 +756,62 @@ bool ARM64DAGToDAGISel::SelectAddrModeRO(SDValue N, unsigned Size,
768
756
if (IsExtendedRegisterWorthFolding &&
769
757
(Ext = getExtendTypeForNode (RHS, true )) != ARM64_AM::InvalidShiftExtend) {
770
758
Base = LHS;
771
- Offset = WidenIfNeeded (CurDAG, RHS.getOperand (0 ));
772
- Imm = CurDAG->getTargetConstant (ARM64_AM::getMemExtendImm (Ext, false ),
773
- MVT::i32);
759
+ Offset = RHS.getOperand (0 );
760
+ SignExtend = CurDAG->getTargetConstant (Ext == ARM64_AM::SXTW, MVT::i32);
774
761
if (isWorthFolding (RHS))
775
762
return true ;
776
763
}
777
764
765
+ return false ;
766
+ }
767
+
768
+ bool ARM64DAGToDAGISel::SelectAddrModeXRO (SDValue N, unsigned Size ,
769
+ SDValue &Base, SDValue &Offset,
770
+ SDValue &SignExtend,
771
+ SDValue &DoShift) {
772
+ if (N.getOpcode () != ISD::ADD)
773
+ return false ;
774
+ SDValue LHS = N.getOperand (0 );
775
+ SDValue RHS = N.getOperand (1 );
776
+
777
+ // We don't want to match immediate adds here, because they are better lowered
778
+ // to the register-immediate addressing modes.
779
+ if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
780
+ return false ;
781
+
782
+ // Check if this particular node is reused in any non-memory related
783
+ // operation. If yes, do not try to fold this node into the address
784
+ // computation, since the computation will be kept.
785
+ const SDNode *Node = N.getNode ();
786
+ for (SDNode *UI : Node->uses ()) {
787
+ if (!isa<MemSDNode>(*UI))
788
+ return false ;
789
+ }
790
+
791
+ // Remember if it is worth folding N when it produces extended register.
792
+ bool IsExtendedRegisterWorthFolding = isWorthFolding (N);
793
+
794
+ // Try to match a shifted extend on the RHS.
795
+ if (IsExtendedRegisterWorthFolding && RHS.getOpcode () == ISD::SHL &&
796
+ SelectExtendedSHL (RHS, Size , false , Offset, SignExtend)) {
797
+ Base = LHS;
798
+ DoShift = CurDAG->getTargetConstant (true , MVT::i32);
799
+ return true ;
800
+ }
801
+
802
+ // Try to match a shifted extend on the LHS.
803
+ if (IsExtendedRegisterWorthFolding && LHS.getOpcode () == ISD::SHL &&
804
+ SelectExtendedSHL (LHS, Size , false , Offset, SignExtend)) {
805
+ Base = RHS;
806
+ DoShift = CurDAG->getTargetConstant (true , MVT::i32);
807
+ return true ;
808
+ }
809
+
778
810
// Match any non-shifted, non-extend, non-immediate add expression.
779
811
Base = LHS;
780
- Offset = WidenIfNeeded (CurDAG, RHS);
781
- Ext = ARM64_AM::UXTX;
782
- Imm = CurDAG->getTargetConstant (ARM64_AM::getMemExtendImm (Ext, false ),
783
- MVT::i32);
812
+ Offset = RHS;
813
+ SignExtend = CurDAG->getTargetConstant (false , MVT::i32);
814
+ DoShift = CurDAG->getTargetConstant (false , MVT::i32);
784
815
// Reg1 + Reg2 is free: no check needed.
785
816
return true ;
786
817
}
0 commit comments