aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Support/Alignment.h28
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp22
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp19
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp9
4 files changed, 55 insertions, 23 deletions
diff --git a/include/llvm/Support/Alignment.h b/include/llvm/Support/Alignment.h
new file mode 100644
index 0000000000..41259b69ba
--- /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 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);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 23d132bb09..5ec74cdc31 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 8699dbc78a..e8bf080c1f 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);
}