aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-10-28 12:59:45 +0000
committerDuncan Sands <baldrick@free.fr>2007-10-28 12:59:45 +0000
commitdc84650679b6330e0fcdd4cf8bc2a351387db7ca (patch)
tree48bce4d7d3999eb1d3ec35f41b1ff8d190e64ddf /lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parent402b6783735a8d4470831133b1df2c98349509d2 (diff)
The guaranteed alignment of ptr+offset is only the minimum of
of offset and the alignment of ptr if these are both powers of 2. While the ptr alignment is guaranteed to be a power of 2, there is no reason to think that offset is. For example, if offset is 12 (the size of a long double on x86-32 linux) and the alignment of ptr is 8, then the alignment of ptr+offset will in general be 4, not 8. Introduce a function MinAlign, lifted from gcc, for computing the minimum guaranteed alignment. I've tried to fix up everywhere under lib/CodeGen/SelectionDAG/. I also changed some places that weren't wrong (because both values were a power of 2), as a defensive change against people copying and pasting the code. Hopefully someone who cares about alignment will review the rest of LLVM and fix up the remaining places. Since I'm on x86 I'm not very motivated to do this myself... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43421 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp22
1 files changed, 13 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5b5a70edb6..d3b8b000a1 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -37,6 +37,7 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -1713,15 +1714,18 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
// read fewer bytes from the same pointer.
unsigned PtrOff =
(MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8;
+ unsigned Alignment = LN0->getAlignment();
SDOperand NewPtr = LN0->getBasePtr();
- if (!TLI.isLittleEndian())
+ if (!TLI.isLittleEndian()) {
NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr,
DAG.getConstant(PtrOff, PtrType));
+ Alignment = MinAlign(Alignment, PtrOff);
+ }
AddToWorkList(NewPtr.Val);
SDOperand Load =
DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), Alignment);
AddToWorkList(N);
CombineTo(N0.Val, Load, Load.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@@ -2879,16 +2883,17 @@ SDOperand DAGCombiner::ReduceLoadWidth(SDNode *N) {
if (!TLI.isLittleEndian())
ShAmt = MVT::getSizeInBits(N0.getValueType()) - ShAmt - EVTBits;
uint64_t PtrOff = ShAmt / 8;
+ unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff);
SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(),
DAG.getConstant(PtrOff, PtrType));
AddToWorkList(NewPtr.Val);
SDOperand Load = (ExtType == ISD::NON_EXTLOAD)
? DAG.getLoad(VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(),
- LN0->isVolatile(), LN0->getAlignment())
+ LN0->isVolatile(), NewAlign)
: DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
- LN0->isVolatile(), LN0->getAlignment());
+ LN0->isVolatile(), NewAlign);
AddToWorkList(N);
if (CombineSRL) {
DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1));
@@ -3905,8 +3910,8 @@ SDOperand DAGCombiner::visitLOAD(SDNode *N) {
// Replace the chain to void dependency.
if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr,
- LD->getSrcValue(), LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
+ LD->getSrcValue(), LD->getSrcValueOffset(),
+ LD->isVolatile(), LD->getAlignment());
} else {
ReplLoad = DAG.getExtLoad(LD->getExtensionType(),
LD->getValueType(0),
@@ -3980,7 +3985,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
ST->getSrcValueOffset(), ST->isVolatile(),
ST->getAlignment());
} else if (TLI.isTypeLegal(MVT::i32)) {
- // Many FP stores are not make apparent until after legalize, e.g. for
+ // Many FP stores are not made apparent until after legalize, e.g. for
// argument passing. Since this is so common, custom legalize the
// 64-bit integer store into two 32-bit stores.
uint64_t Val = CFP->getValueAPF().convertToAPInt().getZExtValue();
@@ -3998,8 +4003,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
DAG.getConstant(4, Ptr.getValueType()));
SVOffset += 4;
- if (Alignment > 4)
- Alignment = 4;
+ Alignment = MinAlign(Alignment, 4U);
SDOperand St1 = DAG.getStore(Chain, Hi, Ptr, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
return DAG.getNode(ISD::TokenFactor, MVT::Other, St0, St1);