diff --git a/include/llvm/Support/Alignment.h b/include/llvm/Support/Alignment.h new file mode 100644 index 00000000000..41259b69ba3 --- /dev/null +++ b/include/llvm/Support/Alignment.h @@ -0,0 +1,28 @@ +//===----------- Alignment.h - Alignment computation ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Duncan Sands and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities for computing alignments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ALIGNMENT_H +#define LLVM_SUPPORT_ALIGNMENT_H + +namespace llvm { + +/// MinAlign - A and B are either alignments or offsets. Return the minimum +/// alignment that may be assumed after adding the two together. + +static inline unsigned MinAlign(unsigned A, unsigned B) { + // The largest power of 2 that divides both A and B. + return (A | B) & -(A | B); +} + +} // end namespace llvm +#endif diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 5b5a70edb6e..d3b8b000a1a 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); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 23d132bb09e..5ec74cdc311 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/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 diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp index 8699dbc78a2..e8bf080c1f6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Target/TargetLowering.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -946,7 +947,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -994,7 +995,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, getIntPtrConstant(IncrementSize)); Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -1019,7 +1020,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, // Load the rest of the low bits. Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -2002,7 +2003,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); Hi = DAG.getStore(Chain, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); }