summaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-06-12 15:42:51 +0000
committerdim <dim@FreeBSD.org>2011-06-12 15:42:51 +0000
commitece02cd5829cea836e9365b0845a8ef042d17b0a (patch)
treeb3032e51d630e8070e9e08d6641648f195316a80 /lib/VMCore
parent2b066988909948dc3d53d01760bc2d71d32f3feb (diff)
downloadFreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.zip
FreeBSD-src-ece02cd5829cea836e9365b0845a8ef042d17b0a.tar.gz
Vendor import of llvm trunk r132879:
http://llvm.org/svn/llvm-project/llvm/trunk@132879
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Attributes.cpp2
-rw-r--r--lib/VMCore/AutoUpgrade.cpp60
-rw-r--r--lib/VMCore/DebugInfoProbe.cpp43
-rw-r--r--lib/VMCore/Function.cpp39
-rw-r--r--lib/VMCore/IRBuilder.cpp31
-rw-r--r--lib/VMCore/InlineAsm.cpp5
-rw-r--r--lib/VMCore/Instructions.cpp167
-rw-r--r--lib/VMCore/PassManager.cpp18
-rw-r--r--lib/VMCore/Type.cpp19
-rw-r--r--lib/VMCore/Verifier.cpp3
10 files changed, 255 insertions, 132 deletions
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 92152a3..ee257db 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -36,6 +36,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "noreturn ";
if (Attrs & Attribute::NoUnwind)
Result += "nounwind ";
+ if (Attrs & Attribute::UWTable)
+ Result += "uwtable ";
if (Attrs & Attribute::InReg)
Result += "inreg ";
if (Attrs & Attribute::NoAlias)
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 4541f38..f8f15ca 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -285,7 +285,33 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
}
break;
- case 'x':
+ case 'x':
+ // This fixes the poorly named crc32 intrinsics
+ if (Name.compare(5, 13, "x86.sse42.crc", 13) == 0) {
+ const char* NewFnName = NULL;
+ if (Name.compare(18, 2, "32", 2) == 0) {
+ if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) {
+ NewFnName = "llvm.x86.sse42.crc32.32.8";
+ } else if (Name.compare(20, 3, ".16") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.32.16";
+ } else if (Name.compare(20, 3, ".32") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.32.32";
+ }
+ }
+ else if (Name.compare(18, 2, "64", 2) == 0) {
+ if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) {
+ NewFnName = "llvm.x86.sse42.crc32.64.8";
+ } else if (Name.compare(20, 3, ".64") == 0 && Name.length() == 23) {
+ NewFnName = "llvm.x86.sse42.crc32.64.64";
+ }
+ }
+ if (NewFnName) {
+ F->setName(NewFnName);
+ NewFn = F;
+ return true;
+ }
+ }
+
// This fixes all MMX shift intrinsic instructions to take a
// x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8.
if (Name.compare(5, 8, "x86.mmx.", 8) == 0) {
@@ -533,6 +559,13 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
// Calls to these instructions are transformed into unaligned loads.
NewFn = 0;
return true;
+ } else if (Name.compare(5, 16, "x86.sse.movnt.ps", 16) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.dq", 17) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.pd", 17) == 0 ||
+ Name.compare(5, 17, "x86.sse2.movnt.i", 16) == 0) {
+ // Calls to these instructions are transformed into nontemporal stores.
+ NewFn = 0;
+ return true;
} else if (Name.compare(5, 17, "x86.ssse3.pshuf.w", 17) == 0) {
// This is an SSE/MMX instruction.
const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext());
@@ -975,6 +1008,31 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Remove intrinsic.
CI->eraseFromParent();
+ } else if (F->getName() == "llvm.x86.sse.movnt.ps" ||
+ F->getName() == "llvm.x86.sse2.movnt.dq" ||
+ F->getName() == "llvm.x86.sse2.movnt.pd" ||
+ F->getName() == "llvm.x86.sse2.movnt.i") {
+ IRBuilder<> Builder(C);
+ Builder.SetInsertPoint(CI->getParent(), CI);
+
+ Module *M = F->getParent();
+ SmallVector<Value *, 1> Elts;
+ Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1));
+ MDNode *Node = MDNode::get(C, Elts);
+
+ Value *Arg0 = CI->getArgOperand(0);
+ Value *Arg1 = CI->getArgOperand(1);
+
+ // Convert the type of the pointer to a pointer to the stored type.
+ Value *BC = Builder.CreateBitCast(Arg0,
+ PointerType::getUnqual(Arg1->getType()),
+ "cast");
+ StoreInst *SI = Builder.CreateStore(Arg1, BC);
+ SI->setMetadata(M->getMDKindID("nontemporal"), Node);
+ SI->setAlignment(16);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
} else {
llvm_unreachable("Unknown function for CallInst upgrade.");
}
diff --git a/lib/VMCore/DebugInfoProbe.cpp b/lib/VMCore/DebugInfoProbe.cpp
index 334c3d8..d1275ff 100644
--- a/lib/VMCore/DebugInfoProbe.cpp
+++ b/lib/VMCore/DebugInfoProbe.cpp
@@ -51,7 +51,6 @@ namespace llvm {
unsigned NumDbgLineLost, NumDbgValueLost;
std::string PassName;
Function *TheFn;
- std::set<unsigned> LineNos;
std::set<MDNode *> DbgVariables;
std::set<Instruction *> MissingDebugLoc;
};
@@ -60,37 +59,19 @@ namespace llvm {
//===----------------------------------------------------------------------===//
// DebugInfoProbeImpl
-static void collect(Function &F, std::set<unsigned> &Lines) {
- for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- const DebugLoc &DL = BI->getDebugLoc();
- unsigned LineNo = 0;
- if (!DL.isUnknown()) {
- if (MDNode *N = DL.getInlinedAt(F.getContext()))
- LineNo = DebugLoc::getFromDILocation(N).getLine();
- else
- LineNo = DL.getLine();
-
- Lines.insert(LineNo);
- }
- }
-}
-
/// initialize - Collect information before running an optimization pass.
void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
if (!EnableDebugInfoProbe) return;
PassName = PName;
- LineNos.clear();
DbgVariables.clear();
+ MissingDebugLoc.clear();
TheFn = &F;
- collect(F, LineNos);
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
- if (BI->getDebugLoc().isUnknown())
+ if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown())
MissingDebugLoc.insert(BI);
if (!isa<DbgInfoIntrinsic>(BI)) continue;
Value *Addr = NULL;
@@ -130,30 +111,16 @@ void DebugInfoProbeImpl::report() {
/// must be used after initialization.
void DebugInfoProbeImpl::finalize(Function &F) {
if (!EnableDebugInfoProbe) return;
- std::set<unsigned> LineNos2;
- collect(F, LineNos2);
assert (TheFn == &F && "Invalid function to measure!");
- for (std::set<unsigned>::iterator I = LineNos.begin(),
- E = LineNos.end(); I != E; ++I) {
- unsigned LineNo = *I;
- if (LineNos2.count(LineNo) == 0) {
- DEBUG(dbgs()
- << "DebugInfoProbe("
- << PassName
- << "): Losing dbg info for source line "
- << LineNo << "\n");
- ++NumDbgLineLost;
- }
- }
-
std::set<MDNode *>DbgVariables2;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
- if (BI->getDebugLoc().isUnknown() &&
+ if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() &&
MissingDebugLoc.count(BI) == 0) {
- DEBUG(dbgs() << "DebugInfoProbe(" << PassName << "): --- ");
+ ++NumDbgLineLost;
+ DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
DEBUG(BI->print(dbgs()));
DEBUG(dbgs() << "\n");
}
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 013c458..0ae0bdb 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -24,6 +24,7 @@
#include "llvm/Support/Threading.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
@@ -78,6 +79,12 @@ bool Argument::hasByValAttr() const {
return getParent()->paramHasAttr(getArgNo()+1, Attribute::ByVal);
}
+unsigned Argument::getParamAlignment() const {
+ assert(getType()->isPointerTy() && "Only pointers have alignments");
+ return getParent()->getParamAlignment(getArgNo()+1);
+
+}
+
/// hasNestAttr - Return true if this argument has the nest attribute on
/// it in its containing function.
bool Argument::hasNestAttr() const {
@@ -406,4 +413,36 @@ bool Function::hasAddressTaken(const User* *PutOffender) const {
return false;
}
+/// callsFunctionThatReturnsTwice - Return true if the function has a call to
+/// setjmp or other function that gcc recognizes as "returning twice".
+///
+/// FIXME: Remove after <rdar://problem/8031714> is fixed.
+/// FIXME: Is the obove FIXME valid?
+bool Function::callsFunctionThatReturnsTwice() const {
+ const Module *M = this->getParent();
+ static const char *ReturnsTwiceFns[] = {
+ "_setjmp",
+ "setjmp",
+ "sigsetjmp",
+ "setjmp_syscall",
+ "savectx",
+ "qsetjmp",
+ "vfork",
+ "getcontext"
+ };
+
+ for (unsigned I = 0; I < array_lengthof(ReturnsTwiceFns); ++I)
+ if (const Function *Callee = M->getFunction(ReturnsTwiceFns[I])) {
+ if (!Callee->use_empty())
+ for (Value::const_use_iterator
+ I = Callee->use_begin(), E = Callee->use_end();
+ I != E; ++I)
+ if (const CallInst *CI = dyn_cast<CallInst>(*I))
+ if (CI->getParent()->getParent() == this)
+ return true;
+ }
+
+ return false;
+}
+
// vim: sw=2 ai
diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp
index 2149155..f2d469a 100644
--- a/lib/VMCore/IRBuilder.cpp
+++ b/lib/VMCore/IRBuilder.cpp
@@ -60,7 +60,6 @@ static CallInst *createCallHelper(Value *Callee, Value *const* Ops,
return CI;
}
-
CallInst *IRBuilderBase::
CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
bool isVolatile, MDNode *TBAATag) {
@@ -118,3 +117,33 @@ CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
return CI;
}
+
+CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
+ assert(isa<PointerType>(Ptr->getType()) &&
+ "lifetime.start only applies to pointers.");
+ Ptr = getCastedInt8PtrValue(Ptr);
+ if (!Size)
+ Size = getInt64(-1);
+ else
+ assert(Size->getType() == getInt64Ty() &&
+ "lifetime.start requires the size to be an i64");
+ Value *Ops[] = { Size, Ptr };
+ Module *M = BB->getParent()->getParent();
+ Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
+ return createCallHelper(TheFn, Ops, 2, this);
+}
+
+CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
+ assert(isa<PointerType>(Ptr->getType()) &&
+ "lifetime.end only applies to pointers.");
+ Ptr = getCastedInt8PtrValue(Ptr);
+ if (!Size)
+ Size = getInt64(-1);
+ else
+ assert(Size->getType() == getInt64Ty() &&
+ "lifetime.end requires the size to be an i64");
+ Value *Ops[] = { Size, Ptr };
+ Module *M = BB->getParent()->getParent();
+ Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
+ return createCallHelper(TheFn, Ops, 2, this);
+}
diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp
index e4f99f0..bd3667d 100644
--- a/lib/VMCore/InlineAsm.cpp
+++ b/lib/VMCore/InlineAsm.cpp
@@ -181,6 +181,11 @@ bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
multipleAlternativeIndex++;
pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes;
++I;
+ } else if (*I == '^') {
+ // Multi-letter constraint
+ // FIXME: For now assuming these are 2-character constraints.
+ pCodes->push_back(std::string(I+1, I+3));
+ I += 3;
} else {
// Single letter constraint.
pCodes->push_back(std::string(I, I+1));
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 61da9b6..8f4eabe 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -2076,6 +2076,7 @@ unsigned CastInst::isEliminableCastPair(
CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
const Twine &Name, Instruction *InsertBefore) {
+ assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
@@ -2098,6 +2099,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd) {
+ assert(castIsValid(op, S, Ty) && "Invalid cast!");
// Construct and return the appropriate CastInst subclass
switch (op) {
case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd);
@@ -2254,60 +2256,56 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
if (SrcTy == DestTy)
return true;
+ if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+ if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+ if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+ // An element by element cast. Valid if casting the elements is valid.
+ SrcTy = SrcVecTy->getElementType();
+ DestTy = DestVecTy->getElementType();
+ }
+
// Get the bit sizes, we'll need these
- unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
- unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
// Run through the possibilities ...
- if (DestTy->isIntegerTy()) { // Casting to integral
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ if (DestTy->isIntegerTy()) { // Casting to integral
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestBits == PTy->getBitWidth();
+ } else if (SrcTy->isVectorTy()) { // Casting from vector
+ return DestBits == SrcBits;
} else { // Casting from something else
return SrcTy->isPointerTy();
}
- } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
- if (SrcTy->isIntegerTy()) { // Casting from integral
+ } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
+ if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
+ } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
return true;
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestBits == PTy->getBitWidth();
+ } else if (SrcTy->isVectorTy()) { // Casting from vector
+ return DestBits == SrcBits;
} else { // Casting from something else
return false;
}
- } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
- // Casting to vector
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- // Casting from vector
- return DestPTy->getBitWidth() == SrcPTy->getBitWidth();
- } else if (DestPTy->getBitWidth() == SrcBits) {
- return true; // float/int -> vector
- } else if (SrcTy->isX86_MMXTy()) {
- return DestPTy->getBitWidth() == 64; // MMX to 64-bit vector
- } else {
- return false;
- }
+ } else if (DestTy->isVectorTy()) { // Casting to vector
+ return DestBits == SrcBits;
} else if (DestTy->isPointerTy()) { // Casting to pointer
- if (SrcTy->isPointerTy()) { // Casting from pointer
+ if (SrcTy->isPointerTy()) { // Casting from pointer
return true;
- } else if (SrcTy->isIntegerTy()) { // Casting from integral
+ } else if (SrcTy->isIntegerTy()) { // Casting from integral
return true;
- } else { // Casting from something else
+ } else { // Casting from something else
return false;
}
} else if (DestTy->isX86_MMXTy()) {
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- return SrcPTy->getBitWidth() == 64; // 64-bit vector to MMX
+ if (SrcTy->isVectorTy()) {
+ return DestBits == SrcBits; // 64-bit vector to MMX
} else {
return false;
}
- } else { // Casting to something else
+ } else { // Casting to something else
return false;
}
}
@@ -2322,14 +2320,27 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
Instruction::CastOps
CastInst::getCastOpcode(
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
- // Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
- unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
- unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
"Only first class types are castable!");
+ if (SrcTy == DestTy)
+ return BitCast;
+
+ if (const VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
+ if (const VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
+ if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+ // An element by element cast. Find the appropriate opcode based on the
+ // element types.
+ SrcTy = SrcVecTy->getElementType();
+ DestTy = DestVecTy->getElementType();
+ }
+
+ // Get the bit sizes, we'll need these
+ unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
+ unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
+
// Run through the possibilities ...
if (DestTy->isIntegerTy()) { // Casting to integral
if (SrcTy->isIntegerTy()) { // Casting from integral
@@ -2348,10 +2359,9 @@ CastInst::getCastOpcode(
return FPToSI; // FP -> sint
else
return FPToUI; // FP -> uint
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestBits == PTy->getBitWidth() &&
- "Casting vector to integer of different width");
- PTy = NULL;
+ } else if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
+ "Casting vector to integer of different width");
return BitCast; // Same size, no-op cast
} else {
assert(SrcTy->isPointerTy() &&
@@ -2372,29 +2382,17 @@ CastInst::getCastOpcode(
} else {
return BitCast; // same size, no-op cast
}
- } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestBits == PTy->getBitWidth() &&
+ } else if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
"Casting vector to floating point of different width");
- PTy = NULL;
return BitCast; // same size, no-op cast
} else {
llvm_unreachable("Casting pointer or non-first class to float");
}
- } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
- if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
- assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
- "Casting vector to vector of different widths");
- SrcPTy = NULL;
- return BitCast; // vector -> vector
- } else if (DestPTy->getBitWidth() == SrcBits) {
- return BitCast; // float/int -> vector
- } else if (SrcTy->isX86_MMXTy()) {
- assert(DestPTy->getBitWidth()==64 &&
- "Casting X86_MMX to vector of wrong width");
- return BitCast; // MMX to 64-bit vector
- } else {
- assert(!"Illegal cast to vector (wrong type or size)");
- }
+ } else if (DestTy->isVectorTy()) {
+ assert(DestBits == SrcBits &&
+ "Illegal cast to vector (wrong type or size)");
+ return BitCast;
} else if (DestTy->isPointerTy()) {
if (SrcTy->isPointerTy()) {
return BitCast; // ptr -> ptr
@@ -2404,9 +2402,8 @@ CastInst::getCastOpcode(
assert(!"Casting pointer to other than pointer or int");
}
} else if (DestTy->isX86_MMXTy()) {
- if (isa<VectorType>(SrcTy)) {
- assert(cast<VectorType>(SrcTy)->getBitWidth() == 64 &&
- "Casting vector of wrong width to X86_MMX");
+ if (SrcTy->isVectorTy()) {
+ assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX");
return BitCast; // 64-bit vector to MMX
} else {
assert(!"Illegal cast to X86_MMX");
@@ -2442,46 +2439,40 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
unsigned DstBitSize = DstTy->getScalarSizeInBits();
+ // If these are vector types, get the lengths of the vectors (using zero for
+ // scalar types means that checking that vector lengths match also checks that
+ // scalars are not being converted to vectors or vectors to scalars).
+ unsigned SrcLength = SrcTy->isVectorTy() ?
+ cast<VectorType>(SrcTy)->getNumElements() : 0;
+ unsigned DstLength = DstTy->isVectorTy() ?
+ cast<VectorType>(DstTy)->getNumElements() : 0;
+
// Switch on the opcode provided
switch (op) {
default: return false; // This is an input error
case Instruction::Trunc:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize > DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize > DstBitSize;
case Instruction::ZExt:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::SExt:
- return SrcTy->isIntOrIntVectorTy() &&
- DstTy->isIntOrIntVectorTy()&& SrcBitSize < DstBitSize;
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::FPTrunc:
- return SrcTy->isFPOrFPVectorTy() &&
- DstTy->isFPOrFPVectorTy() &&
- SrcBitSize > DstBitSize;
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength && SrcBitSize > DstBitSize;
case Instruction::FPExt:
- return SrcTy->isFPOrFPVectorTy() &&
- DstTy->isFPOrFPVectorTy() &&
- SrcBitSize < DstBitSize;
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength && SrcBitSize < DstBitSize;
case Instruction::UIToFP:
case Instruction::SIToFP:
- if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
- if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isIntOrIntVectorTy() &&
- DVTy->getElementType()->isFPOrFPVectorTy() &&
- SVTy->getNumElements() == DVTy->getNumElements();
- }
- }
- return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy();
+ return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() &&
+ SrcLength == DstLength;
case Instruction::FPToUI:
case Instruction::FPToSI:
- if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
- if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- return SVTy->getElementType()->isFPOrFPVectorTy() &&
- DVTy->getElementType()->isIntOrIntVectorTy() &&
- SVTy->getNumElements() == DVTy->getNumElements();
- }
- }
- return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy();
+ return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() &&
+ SrcLength == DstLength;
case Instruction::PtrToInt:
return SrcTy->isPointerTy() && DstTy->isIntegerTy();
case Instruction::IntToPtr:
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 637fa79..5cf2905 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -449,9 +449,9 @@ namespace {
static DebugInfoProbeInfo *TheDebugProbe;
static void createDebugInfoProbe() {
if (TheDebugProbe) return;
-
- // Constructed the first time this is called. This guarantees that the
- // object will be constructed, if -enable-debug-info-probe is set,
+
+ // Constructed the first time this is called. This guarantees that the
+ // object will be constructed, if -enable-debug-info-probe is set,
// before static globals, thus it will be destroyed before them.
static ManagedStatic<DebugInfoProbeInfo> DIP;
TheDebugProbe = &*DIP;
@@ -632,6 +632,7 @@ void PMTopLevelManager::schedulePass(Pass *P) {
Pass *AnalysisPass = findAnalysisPass(*I);
if (!AnalysisPass) {
const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(*I);
+ assert(PI && "Expected required passes to be initialized");
AnalysisPass = PI->createPass();
if (P->getPotentialPassManagerType () ==
AnalysisPass->getPotentialPassManagerType())
@@ -686,6 +687,7 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
// If Pass not found then check the interfaces implemented by Immutable Pass
const PassInfo *PassInf =
PassRegistry::getPassRegistry()->getPassInfo(PI);
+ assert(PassInf && "Expected all immutable passes to be initialized");
const std::vector<const PassInfo*> &ImmPI =
PassInf->getInterfacesImplemented();
for (std::vector<const PassInfo*>::const_iterator II = ImmPI.begin(),
@@ -727,9 +729,11 @@ void PMTopLevelManager::dumpArguments() const {
for (SmallVector<ImmutablePass *, 8>::const_iterator I =
ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I)
if (const PassInfo *PI =
- PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID()))
+ PassRegistry::getPassRegistry()->getPassInfo((*I)->getPassID())) {
+ assert(PI && "Expected all immutable passes to be initialized");
if (!PI->isAnalysisGroup())
dbgs() << " -" << PI->getPassArgument();
+ }
for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
(*I)->dumpPassArguments();
@@ -1183,6 +1187,12 @@ void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
for (unsigned i = 0; i != Set.size(); ++i) {
if (i) dbgs() << ',';
const PassInfo *PInf = PassRegistry::getPassRegistry()->getPassInfo(Set[i]);
+ if (!PInf) {
+ // Some preserved passes, such as AliasAnalysis, may not be initialized by
+ // all drivers.
+ dbgs() << " Uninitialized Pass";
+ continue;
+ }
dbgs() << ' ' << PInf->getPassName();
}
dbgs() << '\n';
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index b15304c..e4496db 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -197,6 +197,25 @@ bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
return false; // Other types have no identity values
}
+bool Type::isEmptyTy() const {
+ const ArrayType *ATy = dyn_cast<ArrayType>(this);
+ if (ATy) {
+ unsigned NumElements = ATy->getNumElements();
+ return NumElements == 0 || ATy->getElementType()->isEmptyTy();
+ }
+
+ const StructType *STy = dyn_cast<StructType>(this);
+ if (STy) {
+ unsigned NumElements = STy->getNumElements();
+ for (unsigned i = 0; i < NumElements; ++i)
+ if (!STy->getElementType(i)->isEmptyTy())
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
unsigned Type::getPrimitiveSizeInBits() const {
switch (getTypeID()) {
case Type::FloatTyID: return 32;
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 8b89110..139e035 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1645,6 +1645,9 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(isa<ConstantInt>(CI.getArgOperand(3)),
"alignment argument of memory intrinsics must be a constant int",
&CI);
+ Assert1(isa<ConstantInt>(CI.getArgOperand(4)),
+ "isvolatile argument of memory intrinsics must be a constant int",
+ &CI);
break;
case Intrinsic::gcroot:
case Intrinsic::gcwrite:
OpenPOWER on IntegriCloud