aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-08-31 20:00:11 +0000
committerOwen Anderson <resistor@mac.com>2011-08-31 20:00:11 +0000
commitd84192fe4f6495e43ee0ff2ac591c14ba36e1e9d (patch)
tree551c45b14980333f05ab0388be50586e55663f36
parente0e42bf0bb1280a881450027aaae6490b4c87fd5 (diff)
When performing instruction selection for LDR_PRE_IMM/LDRB_PRE_IMM, we still need to preserve the sign of the index. This fixes miscompilations of Quicksort in the nightly testsuite, and hopefully others as well.
<rdar://problem/10046188> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138885 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 73a4322b82..681ed94035 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -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
}