//===----------------------------------------------------------------------===//
#include "TransformInternals.h"
-#include "llvm/Function.h"
#include "llvm/iOther.h"
#include "llvm/iPHINode.h"
#include "llvm/iMemory.h"
-#include "llvm/ConstantVals.h"
-#include "llvm/Transforms/Scalar/ConstantHandling.h"
-#include "llvm/Transforms/Scalar/DCE.h"
+#include "llvm/ConstantHandling.h"
#include "llvm/Analysis/Expressions.h"
#include "Support/STLExtras.h"
-#include <map>
#include <algorithm>
#include <iostream>
using std::cerr;
-#include "llvm/Assembly/Writer.h"
-
//#define DEBUG_EXPR_CONVERT 1
static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
analysis::ExprType Expr = analysis::ClassifyExpression(MI->getArraySize());
// Get information about the base datatype being allocated, before & after
- unsigned ReqTypeSize = TD.getTypeSize(Ty);
+ int ReqTypeSize = TD.getTypeSize(Ty);
unsigned OldTypeSize = TD.getTypeSize(MI->getType()->getElementType());
// Must have a scale or offset to analyze it...
// Get the offset and scale of the allocation...
int OffsetVal = Expr.Offset ? getConstantValue(Expr.Offset) : 0;
int ScaleVal = Expr.Scale ? getConstantValue(Expr.Scale) : (Expr.Var ? 1 : 0);
- if (ScaleVal < 0 || OffsetVal < 0) {
- cerr << "malloc of a negative number???\n";
- return false;
- }
// The old type might not be of unit size, take old size into consideration
// here...
- unsigned Offset = (unsigned)OffsetVal * OldTypeSize;
- unsigned Scale = (unsigned)ScaleVal * OldTypeSize;
+ int Offset = OffsetVal * OldTypeSize;
+ int Scale = ScaleVal * OldTypeSize;
// In order to be successful, both the scale and the offset must be a multiple
// of the requested data type's size.
ValueHandle IHandle(VMC, I); // Prevent I from being removed!
- Constant *Dummy = Constant::getNullConstant(Ty);
+ Constant *Dummy = Constant::getNullValue(Ty);
switch (I->getOpcode()) {
case Instruction::Cast:
LoadInst *LI = cast<LoadInst>(I);
assert(!LI->hasIndices() || AllIndicesZero(LI));
- Res = new LoadInst(Constant::getNullConstant(PointerType::get(Ty)), Name);
+ Res = new LoadInst(Constant::getNullValue(PointerType::get(Ty)), Name);
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(LI->getPointerOperand(),
PointerType::get(Ty), VMC));
Indices, &It);
if (ElTy) {
assert(ElTy == PVTy && "Internal error, setup wrong!");
- Res = new GetElementPtrInst(Constant::getNullConstant(NewSrcTy),
+ Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy),
Indices, Name);
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),
//
if (Res == 0) {
const PointerType *NewSrcTy = PointerType::get(PVTy);
- Res = new GetElementPtrInst(Constant::getNullConstant(NewSrcTy),
+ Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy),
GEP->copyIndices(), Name);
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),
I->getType() == I->getOperand(0)->getType())
return false;
+ // Do not allow a 'cast ushort %V to uint' to have it's first operand be
+ // converted to a 'short' type. Doing so changes the way sign promotion
+ // happens, and breaks things. Only allow the cast to take place if the
+ // signedness doesn't change... or if the current cast is not a lossy
+ // conversion.
+ //
+ if (!I->getType()->isLosslesslyConvertableTo(I->getOperand(0)->getType()) &&
+ I->getOperand(0)->getType()->isSigned() != Ty->isSigned())
+ return false;
#if 1
// We also do not allow conversion of a cast that casts from a ptr to array
const Type *NewTy = NewVal->getType();
Constant *Dummy = (NewTy != Type::VoidTy) ?
- Constant::getNullConstant(NewTy) : 0;
+ Constant::getNullValue(NewTy) : 0;
switch (I->getOpcode()) {
case Instruction::Cast:
case Instruction::Store: {
if (I->getOperand(0) == OldVal) { // Replace the source value
const PointerType *NewPT = PointerType::get(NewTy);
- Res = new StoreInst(NewVal, Constant::getNullConstant(NewPT));
+ Res = new StoreInst(NewVal, Constant::getNullValue(NewPT));
VMC.ExprMap[I] = Res;
Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), NewPT, VMC));
} else { // Replace the source pointer
assert(Offset == 0 && ValTy);
}
- Res = new StoreInst(Constant::getNullConstant(ValTy), NewVal, Indices);
+ Res = new StoreInst(Constant::getNullValue(ValTy), NewVal, Indices);
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), ValTy, VMC));
}