When performing instruction selection for LDR_PRE_IMM/LDRB_PRE_IMM, we still need...
authorOwen Anderson <resistor@mac.com>
Wed, 31 Aug 2011 20:00:11 +0000 (20:00 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 31 Aug 2011 20:00:11 +0000 (20:00 +0000)
<rdar://problem/10046188>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138885 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelDAGToDAG.cpp

index 73a4322b820741539ec2cb859f926a8076b85eef..681ed9403546de0b8df6a96ea0fc5295bfa75b13 100644 (file)
@@ -759,8 +759,15 @@ bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
 
 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N,
                                             SDValue &Offset, SDValue &Opc) {
+  unsigned Opcode = Op->getOpcode();
+  ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
+    ? cast<LoadSDNode>(Op)->getAddressingMode()
+    : cast<StoreSDNode>(Op)->getAddressingMode();
+  ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
+    ? ARM_AM::add : ARM_AM::sub;
   int Val;
   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits.
+    if (AddSub == ARM_AM::sub) Val *= -1;
     Offset = CurDAG->getRegister(0, MVT::i32);
     Opc = CurDAG->getTargetConstant(Val, MVT::i32);
     return true;
@@ -2316,7 +2323,7 @@ SDNode *ARMDAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) {
   Ops.push_back(Node->getOperand(1)); // Ptr
   Ops.push_back(Node->getOperand(2)); // Low part of Val1
   Ops.push_back(Node->getOperand(3)); // High part of Val1
-  if (Opc == ARM::ATOMCMPXCHG6432) { 
+  if (Opc == ARM::ATOMCMPXCHG6432) {
     Ops.push_back(Node->getOperand(4)); // Low part of Val2
     Ops.push_back(Node->getOperand(5)); // High part of Val2
   }