From e7a9ac929f32a9ec74a09a64daea107ea4ee116e Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 9 Nov 2007 08:57:19 +0000 Subject: [PATCH] Fix some load/store logic that would be wrong for apints on big-endian machines if the bitwidth is not a multiple of 8. Introduce a new helper, MVT::getStoreSizeInBits, and use it. llvm-svn: 43934 --- llvm/include/llvm/CodeGen/ValueTypes.h | 7 +++++++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 ++++++++---- llvm/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp | 4 ++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 780482b07933..6edf97a52c10 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -243,6 +243,13 @@ namespace MVT { // MVT = Machine Value Types } } + /// MVT::getStoreSizeInBits - Return the number of bits overwritten by a + /// store of the specified value type. + /// + static inline unsigned getStoreSizeInBits(ValueType VT) { + return (getSizeInBits(VT) + 7)/8*8; + } + /// MVT::getIntegerType - Returns the ValueType that represents an integer /// with the given number of bits. /// diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 73d7db413f14..7a6e55e98494 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1713,8 +1713,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { // For big endian targets, we need to add an offset to the pointer to // load the correct bytes. For little endian systems, we merely need to // read fewer bytes from the same pointer. - unsigned PtrOff = - (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8; + unsigned LVTStoreBytes = MVT::getStoreSizeInBits(LoadedVT)/8; + unsigned EVTStoreBytes = MVT::getStoreSizeInBits(EVT)/8; + unsigned PtrOff = LVTStoreBytes - EVTStoreBytes; unsigned Alignment = LN0->getAlignment(); SDOperand NewPtr = LN0->getBasePtr(); if (!TLI.isLittleEndian()) { @@ -2991,8 +2992,11 @@ SDOperand DAGCombiner::ReduceLoadWidth(SDNode *N) { MVT::ValueType PtrType = N0.getOperand(1).getValueType(); // For big endian targets, we need to adjust the offset to the pointer to // load the correct bytes. - if (!TLI.isLittleEndian()) - ShAmt = MVT::getSizeInBits(N0.getValueType()) - ShAmt - EVTBits; + if (!TLI.isLittleEndian()) { + unsigned LVTStoreBits = MVT::getStoreSizeInBits(N0.getValueType()); + unsigned EVTStoreBits = MVT::getStoreSizeInBits(EVT); + ShAmt = LVTStoreBits - EVTStoreBits - ShAmt; + } uint64_t PtrOff = ShAmt / 8; unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp index 11431ee08619..825134130c36 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp @@ -1036,7 +1036,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, // Big-endian - high bits are at low addresses. Favor aligned loads at // the cost of some bit-fiddling. MVT::ValueType EVT = N->getLoadedVT(); - unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8; + unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; unsigned ExcessBits = (EBytes - IncrementSize)*8; @@ -2069,7 +2069,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { GetExpandedOp(N->getValue(), Lo, Hi); MVT::ValueType EVT = N->getStoredVT(); - unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8; + unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8; unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; unsigned ExcessBits = (EBytes - IncrementSize)*8; MVT::ValueType HiVT =