[llvm] r352475 - [ARM] Use sub for negative offset load/store in thumb1

David Green via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 29 02:40:31 PST 2019


Author: dmgreen
Date: Tue Jan 29 02:40:31 2019
New Revision: 352475

URL: http://llvm.org/viewvc/llvm-project?rev=352475&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/test/CodeGen/ARM/load.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=352475&r1=352474&r2=352475&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Jan 29 02:40:31 2019
@@ -130,6 +130,7 @@ public:
 
   // Thumb Addressing Modes:
   bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);
+  bool SelectThumbAddrModeRRSext(SDValue N, SDValue &Base, SDValue &Offset);
   bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base,
                                 SDValue &OffImm);
   bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base,
@@ -1032,8 +1033,22 @@ bool ARMDAGToDAGISel::SelectAddrModePC(S
 //                         Thumb Addressing Modes
 //===----------------------------------------------------------------------===//
 
-bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
-                                            SDValue &Base, SDValue &Offset){
+static bool shouldUseZeroOffsetLdSt(SDValue N) {
+  // Negative numbers are difficult to materialise in thumb1. If we are
+  // selecting the add of a negative, instead try to select ri with a zero
+  // offset, so create the add node directly which will become a sub.
+  if (N.getOpcode() != ISD::ADD)
+    return false;
+
+  // Look for an imm which is not legal for ld/st, but is legal for sub.
+  if (auto C = dyn_cast<ConstantSDNode>(N.getOperand(1)))
+    return C->getSExtValue() < 0 && C->getSExtValue() >= -255;
+
+  return false;
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeRRSext(SDValue N, SDValue &Base,
+                                                SDValue &Offset) {
   if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) {
     ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N);
     if (!NC || !NC->isNullValue())
@@ -1048,9 +1063,22 @@ bool ARMDAGToDAGISel::SelectThumbAddrMod
   return true;
 }
 
+bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, SDValue &Base,
+                                            SDValue &Offset) {
+  if (shouldUseZeroOffsetLdSt(N))
+    return false; // Select ri instead
+  return SelectThumbAddrModeRRSext(N, Base, Offset);
+}
+
 bool
 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale,
                                           SDValue &Base, SDValue &OffImm) {
+  if (shouldUseZeroOffsetLdSt(N)) {
+    Base = N;
+    OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32);
+    return true;
+  }
+
   if (!CurDAG->isBaseWithConstantOffset(N)) {
     if (N.getOpcode() == ISD::ADD) {
       return false; // We want to select register offset instead

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=352475&r1=352474&r2=352475&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Jan 29 02:40:31 2019
@@ -187,6 +187,19 @@ def t_addrmode_rr : MemOperand,
   let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
 }
 
+// t_addrmode_rr_sext := reg + reg
+//
+// This is similar to t_addrmode_rr, but uses different heuristics for
+// ldrsb/ldrsh.
+def t_addrmode_rr_sext : MemOperand,
+                    ComplexPattern<i32, 2, "SelectThumbAddrModeRRSext", []> {
+  let EncoderMethod = "getThumbAddrModeRegRegOpValue";
+  let PrintMethod = "printThumbAddrModeRROperand";
+  let DecoderMethod = "DecodeThumbAddrModeRR";
+  let ParserMatchClass = t_addrmode_rr_asm_operand;
+  let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg);
+}
+
 // t_addrmode_rrs := reg + reg
 //
 // We use separate scaled versions because the Select* functions need
@@ -731,17 +744,17 @@ defm tLDRH : thumb_ld_rr_ri_enc<0b101, 0
 
 let AddedComplexity = 10 in
 def tLDRSB :                    // A8.6.80
-  T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
+  T1pILdStEncode<0b011, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
                  AddrModeT1_1, IIC_iLoad_bh_r,
                  "ldrsb", "\t$Rt, $addr",
-                 [(set tGPR:$Rt, (sextloadi8 t_addrmode_rr:$addr))]>;
+                 [(set tGPR:$Rt, (sextloadi8 t_addrmode_rr_sext:$addr))]>;
 
 let AddedComplexity = 10 in
 def tLDRSH :                    // A8.6.84
-  T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr:$addr),
+  T1pILdStEncode<0b111, (outs tGPR:$Rt), (ins t_addrmode_rr_sext:$addr),
                  AddrModeT1_2, IIC_iLoad_bh_r,
                  "ldrsh", "\t$Rt, $addr",
-                 [(set tGPR:$Rt, (sextloadi16 t_addrmode_rr:$addr))]>;
+                 [(set tGPR:$Rt, (sextloadi16 t_addrmode_rr_sext:$addr))]>;
 
 
 def tSTRspi : T1pIs<(outs), (ins tGPR:$Rt, t_addrmode_sp:$addr), IIC_iStore_i,

Modified: llvm/trunk/test/CodeGen/ARM/load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/load.ll?rev=352475&r1=352474&r2=352475&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/load.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/load.ll Tue Jan 29 02:40:31 2019
@@ -608,9 +608,8 @@ entry:
 define i32 @ldrb_ri_negative(i8* %p) {
 ; CHECK-T1-LABEL: ldrb_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #0
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldrb r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    ldrb r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldrb_ri_negative:
@@ -627,9 +626,8 @@ entry:
 define i32 @ldrh_ri_negative(i8* %p) {
 ; CHECK-T1-LABEL: ldrh_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #0
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldrh r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    ldrh r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldrh_ri_negative:
@@ -647,9 +645,8 @@ entry:
 define i32 @ldr_ri_negative(i8* %p) {
 ; CHECK-T1-LABEL: ldr_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #0
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldr r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    ldr r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldr_ri_negative:
@@ -666,9 +663,8 @@ entry:
 define void @strb_ri_negative(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: strb_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #0
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    strb r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    strb r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: strb_ri_negative:
@@ -685,9 +681,8 @@ entry:
 define void @strh_ri_negative(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: strh_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #0
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    strh r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    strh r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: strh_ri_negative:
@@ -705,9 +700,8 @@ entry:
 define void @str_ri_negative(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: str_ri_negative:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #0
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    str r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, r0, #1
+; CHECK-T1-NEXT:    str r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: str_ri_negative:
@@ -766,9 +760,8 @@ entry:
 define i32 @ldrb_ri_negative255(i8* %p) {
 ; CHECK-T1-LABEL: ldrb_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #254
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldrb r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    ldrb r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldrb_ri_negative255:
@@ -785,9 +778,8 @@ entry:
 define i32 @ldrh_ri_negative255(i8* %p) {
 ; CHECK-T1-LABEL: ldrh_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #254
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldrh r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    ldrh r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldrh_ri_negative255:
@@ -805,9 +797,8 @@ entry:
 define i32 @ldr_ri_negative255(i8* %p) {
 ; CHECK-T1-LABEL: ldr_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r1, #254
-; CHECK-T1-NEXT:    mvns r1, r1
-; CHECK-T1-NEXT:    ldr r0, [r0, r1]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    ldr r0, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: ldr_ri_negative255:
@@ -824,9 +815,8 @@ entry:
 define void @strb_ri_negative255(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: strb_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #254
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    strb r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    strb r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: strb_ri_negative255:
@@ -843,9 +833,8 @@ entry:
 define void @strh_ri_negative255(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: strh_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #254
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    strh r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    strh r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: strh_ri_negative255:
@@ -863,9 +852,8 @@ entry:
 define void @str_ri_negative255(i8* %p, i32 %x) {
 ; CHECK-T1-LABEL: str_ri_negative255:
 ; CHECK-T1:       @ %bb.0: @ %entry
-; CHECK-T1-NEXT:    movs r2, #254
-; CHECK-T1-NEXT:    mvns r2, r2
-; CHECK-T1-NEXT:    str r1, [r0, r2]
+; CHECK-T1-NEXT:    subs r0, #255
+; CHECK-T1-NEXT:    str r1, [r0]
 ; CHECK-T1-NEXT:    bx lr
 ;
 ; CHECK-T2-LABEL: str_ri_negative255:




More information about the llvm-commits mailing list