Skip to content

Commit 54b0115

Browse files
committedJan 29, 2019
[ARM] Use sub for negative offset load/store in thumb1
This attempts to optimise negative values used in load/store operands a little. We currently try to selct them as rr, materialising the negative constant using a MOV/MVN pair. This instead selects ri with an immediate of 0, forcing the add node to become a simpler sub. Differential Revision: https://reviews.llvm.org/D57121 llvm-svn: 352475
1 parent 0b7fce6 commit 54b0115

File tree

3 files changed

+71
-42
lines changed

3 files changed

+71
-42
lines changed
 

Diff for: ‎llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
130130

131131
// Thumb Addressing Modes:
132132
bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);
133+
bool SelectThumbAddrModeRRSext(SDValue N, SDValue &Base, SDValue &Offset);
133134
bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base,
134135
SDValue &OffImm);
135136
bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base,
@@ -1032,8 +1033,22 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N,
10321033
// Thumb Addressing Modes
10331034
//===----------------------------------------------------------------------===//
10341035

1035-
bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
1036-
SDValue &Base, SDValue &Offset){
1036+
static bool shouldUseZeroOffsetLdSt(SDValue N) {
1037+
// Negative numbers are difficult to materialise in thumb1. If we are
1038+
// selecting the add of a negative, instead try to select ri with a zero
1039+
// offset, so create the add node directly which will become a sub.
1040+
if (N.getOpcode() != ISD::ADD)
1041+
return false;
1042+
1043+
// Look for an imm which is not legal for ld/st, but is legal for sub.
1044+
if (auto C = dyn_cast<ConstantSDNode>(N.getOperand(1)))
1045+
return C->getSExtValue() < 0 && C->getSExtValue() >= -255;
1046+
1047+
return false;
1048+
}
1049+
1050+
bool ARMDAGToDAGISel::SelectThumbAddrModeRRSext(SDValue N, SDValue &Base,
1051+
SDValue &Offset) {
10371052
if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) {
10381053
ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N);
10391054
if (!NC || !NC->isNullValue())
@@ -1048,9 +1063,22 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
10481063
return true;
10491064
}
10501065

1066+
bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, SDValue &Base,
1067+
SDValue &Offset) {
1068+
if (shouldUseZeroOffsetLdSt(N))
1069+
return false; // Select ri instead
1070+
return SelectThumbAddrModeRRSext(N, Base, Offset);
1071+
}
1072+
10511073
bool
10521074
ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale,
10531075
SDValue &Base, SDValue &OffImm) {
1076+
if (shouldUseZeroOffsetLdSt(N)) {
1077+
Base = N;
1078+
OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32);
1079+
return true;
1080+
}
1081+
10541082
if (!CurDAG->isBaseWithConstantOffset(N)) {
10551083
if (N.getOpcode() == ISD::ADD) {
10561084
return false; // We want to select register offset instead

Diff for: ‎llvm/lib/Target/ARM/ARMInstrThumb.td

+17-4
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ def t_addrmode_rr : MemOperand,
187187
let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
188188
}
189189

190+
// t_addrmode_rr_sext := reg + reg
191+
//
192+
// This is similar to t_addrmode_rr, but uses different heuristics for
193+
// ldrsb/ldrsh.
194+
def t_addrmode_rr_sext : MemOperand,
195+
ComplexPattern<i32, 2, "SelectThumbAddrModeRRSext", []> {
196+
let EncoderMethod = "getThumbAddrModeRegRegOpValue";
197+
let PrintMethod = "printThumbAddrModeRROperand";
198+
let DecoderMethod = "DecodeThumbAddrModeRR";
199+
let ParserMatchClass = t_addrmode_rr_asm_operand;
200+
let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
201+
}
202+
190203
// t_addrmode_rrs := reg + reg
191204
//
192205
// We use separate scaled versions because the Select* functions need
@@ -731,17 +744,17 @@ defm tLDRH : thumb_ld_rr_ri_enc<0b101, 0b1000, t_addrmode_rr,
731744

732745
let AddedComplexity = 10 in
733746
def tLDRSB : // A8.6.80
734-
T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
747+
T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
735748
AddrModeT1_1, IIC_iLoad_bh_r,
736749
"ldrsb", "\t$Rt, $addr",
737-
[(set tGPR:$Rt, (sextloadi8 t_addrmode_rr:$addr))]>;
750+
[(set tGPR:$Rt, (sextloadi8 t_addrmode_rr_sext:$addr))]>;
738751

739752
let AddedComplexity = 10 in
740753
def tLDRSH : // A8.6.84
741-
T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
754+
T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
742755
AddrModeT1_2, IIC_iLoad_bh_r,
743756
"ldrsh", "\t$Rt, $addr",
744-
[(set tGPR:$Rt, (sextloadi16 t_addrmode_rr:$addr))]>;
757+
[(set tGPR:$Rt, (sextloadi16 t_addrmode_rr_sext:$addr))]>;
745758

746759

747760
def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,

Diff for: ‎llvm/test/CodeGen/ARM/load.ll

+24-36
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,8 @@ entry:
608608
define i32 @ldrb_ri_negative(i8* %p) {
609609
; CHECK-T1-LABEL: ldrb_ri_negative:
610610
; CHECK-T1: @ %bb.0: @ %entry
611-
; CHECK-T1-NEXT: movs r1, #0
612-
; CHECK-T1-NEXT: mvns r1, r1
613-
; CHECK-T1-NEXT: ldrb r0, [r0, r1]
611+
; CHECK-T1-NEXT: subs r0, r0, #1
612+
; CHECK-T1-NEXT: ldrb r0, [r0]
614613
; CHECK-T1-NEXT: bx lr
615614
;
616615
; CHECK-T2-LABEL: ldrb_ri_negative:
@@ -627,9 +626,8 @@ entry:
627626
define i32 @ldrh_ri_negative(i8* %p) {
628627
; CHECK-T1-LABEL: ldrh_ri_negative:
629628
; CHECK-T1: @ %bb.0: @ %entry
630-
; CHECK-T1-NEXT: movs r1, #0
631-
; CHECK-T1-NEXT: mvns r1, r1
632-
; CHECK-T1-NEXT: ldrh r0, [r0, r1]
629+
; CHECK-T1-NEXT: subs r0, r0, #1
630+
; CHECK-T1-NEXT: ldrh r0, [r0]
633631
; CHECK-T1-NEXT: bx lr
634632
;
635633
; CHECK-T2-LABEL: ldrh_ri_negative:
@@ -647,9 +645,8 @@ entry:
647645
define i32 @ldr_ri_negative(i8* %p) {
648646
; CHECK-T1-LABEL: ldr_ri_negative:
649647
; CHECK-T1: @ %bb.0: @ %entry
650-
; CHECK-T1-NEXT: movs r1, #0
651-
; CHECK-T1-NEXT: mvns r1, r1
652-
; CHECK-T1-NEXT: ldr r0, [r0, r1]
648+
; CHECK-T1-NEXT: subs r0, r0, #1
649+
; CHECK-T1-NEXT: ldr r0, [r0]
653650
; CHECK-T1-NEXT: bx lr
654651
;
655652
; CHECK-T2-LABEL: ldr_ri_negative:
@@ -666,9 +663,8 @@ entry:
666663
define void @strb_ri_negative(i8* %p, i32 %x) {
667664
; CHECK-T1-LABEL: strb_ri_negative:
668665
; CHECK-T1: @ %bb.0: @ %entry
669-
; CHECK-T1-NEXT: movs r2, #0
670-
; CHECK-T1-NEXT: mvns r2, r2
671-
; CHECK-T1-NEXT: strb r1, [r0, r2]
666+
; CHECK-T1-NEXT: subs r0, r0, #1
667+
; CHECK-T1-NEXT: strb r1, [r0]
672668
; CHECK-T1-NEXT: bx lr
673669
;
674670
; CHECK-T2-LABEL: strb_ri_negative:
@@ -685,9 +681,8 @@ entry:
685681
define void @strh_ri_negative(i8* %p, i32 %x) {
686682
; CHECK-T1-LABEL: strh_ri_negative:
687683
; CHECK-T1: @ %bb.0: @ %entry
688-
; CHECK-T1-NEXT: movs r2, #0
689-
; CHECK-T1-NEXT: mvns r2, r2
690-
; CHECK-T1-NEXT: strh r1, [r0, r2]
684+
; CHECK-T1-NEXT: subs r0, r0, #1
685+
; CHECK-T1-NEXT: strh r1, [r0]
691686
; CHECK-T1-NEXT: bx lr
692687
;
693688
; CHECK-T2-LABEL: strh_ri_negative:
@@ -705,9 +700,8 @@ entry:
705700
define void @str_ri_negative(i8* %p, i32 %x) {
706701
; CHECK-T1-LABEL: str_ri_negative:
707702
; CHECK-T1: @ %bb.0: @ %entry
708-
; CHECK-T1-NEXT: movs r2, #0
709-
; CHECK-T1-NEXT: mvns r2, r2
710-
; CHECK-T1-NEXT: str r1, [r0, r2]
703+
; CHECK-T1-NEXT: subs r0, r0, #1
704+
; CHECK-T1-NEXT: str r1, [r0]
711705
; CHECK-T1-NEXT: bx lr
712706
;
713707
; CHECK-T2-LABEL: str_ri_negative:
@@ -766,9 +760,8 @@ entry:
766760
define i32 @ldrb_ri_negative255(i8* %p) {
767761
; CHECK-T1-LABEL: ldrb_ri_negative255:
768762
; CHECK-T1: @ %bb.0: @ %entry
769-
; CHECK-T1-NEXT: movs r1, #254
770-
; CHECK-T1-NEXT: mvns r1, r1
771-
; CHECK-T1-NEXT: ldrb r0, [r0, r1]
763+
; CHECK-T1-NEXT: subs r0, #255
764+
; CHECK-T1-NEXT: ldrb r0, [r0]
772765
; CHECK-T1-NEXT: bx lr
773766
;
774767
; CHECK-T2-LABEL: ldrb_ri_negative255:
@@ -785,9 +778,8 @@ entry:
785778
define i32 @ldrh_ri_negative255(i8* %p) {
786779
; CHECK-T1-LABEL: ldrh_ri_negative255:
787780
; CHECK-T1: @ %bb.0: @ %entry
788-
; CHECK-T1-NEXT: movs r1, #254
789-
; CHECK-T1-NEXT: mvns r1, r1
790-
; CHECK-T1-NEXT: ldrh r0, [r0, r1]
781+
; CHECK-T1-NEXT: subs r0, #255
782+
; CHECK-T1-NEXT: ldrh r0, [r0]
791783
; CHECK-T1-NEXT: bx lr
792784
;
793785
; CHECK-T2-LABEL: ldrh_ri_negative255:
@@ -805,9 +797,8 @@ entry:
805797
define i32 @ldr_ri_negative255(i8* %p) {
806798
; CHECK-T1-LABEL: ldr_ri_negative255:
807799
; CHECK-T1: @ %bb.0: @ %entry
808-
; CHECK-T1-NEXT: movs r1, #254
809-
; CHECK-T1-NEXT: mvns r1, r1
810-
; CHECK-T1-NEXT: ldr r0, [r0, r1]
800+
; CHECK-T1-NEXT: subs r0, #255
801+
; CHECK-T1-NEXT: ldr r0, [r0]
811802
; CHECK-T1-NEXT: bx lr
812803
;
813804
; CHECK-T2-LABEL: ldr_ri_negative255:
@@ -824,9 +815,8 @@ entry:
824815
define void @strb_ri_negative255(i8* %p, i32 %x) {
825816
; CHECK-T1-LABEL: strb_ri_negative255:
826817
; CHECK-T1: @ %bb.0: @ %entry
827-
; CHECK-T1-NEXT: movs r2, #254
828-
; CHECK-T1-NEXT: mvns r2, r2
829-
; CHECK-T1-NEXT: strb r1, [r0, r2]
818+
; CHECK-T1-NEXT: subs r0, #255
819+
; CHECK-T1-NEXT: strb r1, [r0]
830820
; CHECK-T1-NEXT: bx lr
831821
;
832822
; CHECK-T2-LABEL: strb_ri_negative255:
@@ -843,9 +833,8 @@ entry:
843833
define void @strh_ri_negative255(i8* %p, i32 %x) {
844834
; CHECK-T1-LABEL: strh_ri_negative255:
845835
; CHECK-T1: @ %bb.0: @ %entry
846-
; CHECK-T1-NEXT: movs r2, #254
847-
; CHECK-T1-NEXT: mvns r2, r2
848-
; CHECK-T1-NEXT: strh r1, [r0, r2]
836+
; CHECK-T1-NEXT: subs r0, #255
837+
; CHECK-T1-NEXT: strh r1, [r0]
849838
; CHECK-T1-NEXT: bx lr
850839
;
851840
; CHECK-T2-LABEL: strh_ri_negative255:
@@ -863,9 +852,8 @@ entry:
863852
define void @str_ri_negative255(i8* %p, i32 %x) {
864853
; CHECK-T1-LABEL: str_ri_negative255:
865854
; CHECK-T1: @ %bb.0: @ %entry
866-
; CHECK-T1-NEXT: movs r2, #254
867-
; CHECK-T1-NEXT: mvns r2, r2
868-
; CHECK-T1-NEXT: str r1, [r0, r2]
855+
; CHECK-T1-NEXT: subs r0, #255
856+
; CHECK-T1-NEXT: str r1, [r0]
869857
; CHECK-T1-NEXT: bx lr
870858
;
871859
; CHECK-T2-LABEL: str_ri_negative255:

0 commit comments

Comments
 (0)
Please sign in to comment.