diff options
| author | Duncan Sands <baldrick@free.fr> | 2007-10-28 12:59:45 +0000 |
|---|---|---|
| committer | Duncan Sands <baldrick@free.fr> | 2007-10-28 12:59:45 +0000 |
| commit | 1826deda685d7f6eed9a20515e5476d4fd8505b9 (patch) | |
| tree | 761f1b9df81e840207ea2c987f13abd2227c4cbd /llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | |
| parent | c826ac533bea863673501dc986902bb192fa9d73 (diff) | |
| download | bcm5719-llvm-1826deda685d7f6eed9a20515e5476d4fd8505b9.tar.gz bcm5719-llvm-1826deda685d7f6eed9a20515e5476d4fd8505b9.zip | |
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...
llvm-svn: 43421
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 23d132bb09e..5ec74cdc311 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -23,9 +23,10 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -602,6 +603,7 @@ SDOperand ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, ST->isVolatile(), Alignment); Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); + Alignment = MinAlign(Alignment, IncrementSize); Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr, ST->getSrcValue(), SVOffset + IncrementSize, NewStoredVT, ST->isVolatile(), Alignment); @@ -660,7 +662,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } else { Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset, NewLoadedVT,LD->isVolatile(), Alignment); @@ -668,7 +670,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } // aggregate the two parts @@ -2055,7 +2057,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, getIntPtrConstant(4)); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, - isVolatile, std::max(Alignment, 4U)); + isVolatile, MinAlign(Alignment, 4U)); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); break; @@ -2164,8 +2166,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { assert(isTypeLegal(Tmp2.getValueType()) && "Pointers must be legal!"); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); @@ -5429,8 +5430,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset, isVolatile, Alignment); @@ -6336,8 +6336,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the |

