Commit 3472e2a5 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r341642:

------------------------------------------------------------------------
r341642 | tnorthover | 2018-09-07 11:21:25 +0200 (Fri, 07 Sep 2018) | 8 lines

ARM: fix Thumb2 CodeGen for ldrex with folded frame-index.

Because t2LDREX (& t2STREX) were marked as AddrModeNone, but did allow a
FrameIndex operand, rewriteT2FrameIndex asserted. This gives them a
proper addressing-mode and tells the rewriter about it so that encodable
offsets are exploited and others are rejected.

Should fix PR38828.
------------------------------------------------------------------------

llvm-svn: 341783
parent 3065b0a7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1514,6 +1514,7 @@ static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
          break;
        case ARMII::AddrMode5:
        case ARMII::AddrModeT2_i8s4:
        case ARMII::AddrModeT2_ldrex:
          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
          break;
        case ARMII::AddrModeT2_i12:
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ def AddrModeT2_pc : AddrMode<14>;
def AddrModeT2_i8s4 : AddrMode<15>;
def AddrMode_i12    : AddrMode<16>;
def AddrMode5FP16   : AddrMode<17>;
def AddrModeT2_ldrex : AddrMode<18>;

// Load / store index mode.
class IndexMode<bits<2> val> {
+2 −2
Original line number Diff line number Diff line
@@ -3267,7 +3267,7 @@ def t2LDREXH : T2I_ldrex<0b0101, (outs rGPR:$Rt), (ins addr_offset_none:$addr),
                         [(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>,
               Requires<[IsThumb, HasV8MBaseline]>;
def t2LDREX  : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr),
                       AddrModeNone, 4, NoItinerary,
                       AddrModeT2_ldrex, 4, NoItinerary,
                       "ldrex", "\t$Rt, $addr", "",
                     [(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]>,
               Requires<[IsThumb, HasV8MBaseline]> {
@@ -3346,7 +3346,7 @@ def t2STREXH : T2I_strex<0b0101, (outs rGPR:$Rd),

def t2STREX  : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt,
                             t2addrmode_imm0_1020s4:$addr),
                  AddrModeNone, 4, NoItinerary,
                  AddrModeT2_ldrex, 4, NoItinerary,
                  "strex", "\t$Rd, $Rt, $addr", "",
                  [(set rGPR:$Rd,
                        (strex_4 rGPR:$Rt, t2addrmode_imm0_1020s4:$addr))]>,
+3 −1
Original line number Diff line number Diff line
@@ -201,7 +201,8 @@ namespace ARMII {
    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
    AddrModeT2_i8s4 = 15, // i8 * 4
    AddrMode_i12    = 16,
    AddrMode5FP16   = 17  // i8 * 2
    AddrMode5FP16   = 17,  // i8 * 2
    AddrModeT2_ldrex = 18, // i8 * 4, with unscaled offset in MCInst
  };

  inline static const char *AddrModeToString(AddrMode addrmode) {
@@ -224,6 +225,7 @@ namespace ARMII {
    case AddrModeT2_pc:   return "AddrModeT2_pc";
    case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
    case AddrMode_i12:    return "AddrMode_i12";
    case AddrModeT2_ldrex:return "AddrModeT2_ldrex";
    }
  }

+5 −0
Original line number Diff line number Diff line
@@ -621,6 +621,11 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
      // MCInst operand expects already scaled value.
      Scale = 1;
      assert((Offset & 3) == 0 && "Can't encode this offset!");
    } else if (AddrMode == ARMII::AddrModeT2_ldrex) {
      Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
      NumBits = 8; // 8 bits scaled by 4
      Scale = 4;
      assert((Offset & 3) == 0 && "Can't encode this offset!");
    } else {
      llvm_unreachable("Unsupported addressing mode!");
    }
Loading