forked from OSchip/llvm-project
Constant fold casts from things like <4 x int> -> <4 x uint>, likewise int<->fp.
llvm-svn: 27336
This commit is contained in:
parent
9b2d6e7886
commit
6b3f475d23
|
@ -24,6 +24,7 @@
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -621,6 +622,81 @@ static unsigned getSize(const Type *Ty) {
|
||||||
return S ? S : 8; // Treat pointers at 8 bytes
|
return S ? S : 8; // Treat pointers at 8 bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// CastConstantPacked - Convert the specified ConstantPacked node to the
|
||||||
|
/// specified packed type. At this point, we know that the elements of the
|
||||||
|
/// input packed constant are all simple integer or FP values.
|
||||||
|
static Constant *CastConstantPacked(ConstantPacked *CP,
|
||||||
|
const PackedType *DstTy) {
|
||||||
|
unsigned SrcNumElts = CP->getType()->getNumElements();
|
||||||
|
unsigned DstNumElts = DstTy->getNumElements();
|
||||||
|
const Type *SrcEltTy = CP->getType()->getElementType();
|
||||||
|
const Type *DstEltTy = DstTy->getElementType();
|
||||||
|
|
||||||
|
// If both vectors have the same number of elements (thus, the elements
|
||||||
|
// are the same size), perform the conversion now.
|
||||||
|
if (SrcNumElts == DstNumElts) {
|
||||||
|
std::vector<Constant*> Result;
|
||||||
|
|
||||||
|
// If the src and dest elements are both integers, just cast each one
|
||||||
|
// which will do the appropriate bit-convert.
|
||||||
|
if (SrcEltTy->isIntegral() && DstEltTy->isIntegral()) {
|
||||||
|
for (unsigned i = 0; i != SrcNumElts; ++i)
|
||||||
|
Result.push_back(ConstantExpr::getCast(CP->getOperand(i),
|
||||||
|
DstEltTy));
|
||||||
|
return ConstantPacked::get(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SrcEltTy->isIntegral()) {
|
||||||
|
// Otherwise, this is an int-to-fp cast.
|
||||||
|
assert(DstEltTy->isFloatingPoint());
|
||||||
|
if (DstEltTy->getTypeID() == Type::DoubleTyID) {
|
||||||
|
for (unsigned i = 0; i != SrcNumElts; ++i) {
|
||||||
|
double V =
|
||||||
|
BitsToDouble(cast<ConstantInt>(CP->getOperand(i))->getRawValue());
|
||||||
|
Result.push_back(ConstantFP::get(Type::DoubleTy, V));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Result);
|
||||||
|
}
|
||||||
|
assert(DstEltTy == Type::FloatTy && "Unknown fp type!");
|
||||||
|
for (unsigned i = 0; i != SrcNumElts; ++i) {
|
||||||
|
float V =
|
||||||
|
BitsToFloat(cast<ConstantInt>(CP->getOperand(i))->getRawValue());
|
||||||
|
Result.push_back(ConstantFP::get(Type::FloatTy, V));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, this is an fp-to-int cast.
|
||||||
|
assert(SrcEltTy->isFloatingPoint() && DstEltTy->isIntegral());
|
||||||
|
|
||||||
|
if (SrcEltTy->getTypeID() == Type::DoubleTyID) {
|
||||||
|
for (unsigned i = 0; i != SrcNumElts; ++i) {
|
||||||
|
uint64_t V =
|
||||||
|
DoubleToBits(cast<ConstantFP>(CP->getOperand(i))->getValue());
|
||||||
|
Constant *C = ConstantUInt::get(Type::ULongTy, V);
|
||||||
|
Result.push_back(ConstantExpr::getCast(C, DstEltTy));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(SrcEltTy->getTypeID() == Type::FloatTyID);
|
||||||
|
for (unsigned i = 0; i != SrcNumElts; ++i) {
|
||||||
|
unsigned V = FloatToBits(cast<ConstantFP>(CP->getOperand(i))->getValue());
|
||||||
|
Constant *C = ConstantUInt::get(Type::UIntTy, V);
|
||||||
|
Result.push_back(ConstantExpr::getCast(C, DstEltTy));
|
||||||
|
}
|
||||||
|
return ConstantPacked::get(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, this is a cast that changes element count and size. Handle
|
||||||
|
// casts which shrink the elements here.
|
||||||
|
|
||||||
|
// FIXME: We need to know endianness to do this!
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
|
Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
|
||||||
const Type *DestTy) {
|
const Type *DestTy) {
|
||||||
if (V->getType() == DestTy) return (Constant*)V;
|
if (V->getType() == DestTy) return (Constant*)V;
|
||||||
|
@ -688,6 +764,38 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
|
||||||
if (ElTy == DPTy->getElementType())
|
if (ElTy == DPTy->getElementType())
|
||||||
return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList);
|
return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle casts from one packed constant to another. We know that the src and
|
||||||
|
// dest type have the same size.
|
||||||
|
if (const PackedType *DestPTy = dyn_cast<PackedType>(DestTy)) {
|
||||||
|
if (const PackedType *SrcTy = dyn_cast<PackedType>(V->getType())) {
|
||||||
|
assert(DestPTy->getElementType()->getPrimitiveSizeInBits() *
|
||||||
|
DestPTy->getNumElements() ==
|
||||||
|
SrcTy->getElementType()->getPrimitiveSizeInBits() *
|
||||||
|
SrcTy->getNumElements() && "Not cast between same sized vectors!");
|
||||||
|
if (isa<ConstantAggregateZero>(V))
|
||||||
|
return Constant::getNullValue(DestTy);
|
||||||
|
if (isa<UndefValue>(V))
|
||||||
|
return UndefValue::get(DestTy);
|
||||||
|
if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(V)) {
|
||||||
|
// This is a cast from a ConstantPacked of one type to a ConstantPacked
|
||||||
|
// of another type. Check to see if all elements of the input are
|
||||||
|
// simple.
|
||||||
|
bool AllSimpleConstants = true;
|
||||||
|
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) {
|
||||||
|
if (!isa<ConstantInt>(CP->getOperand(i)) &&
|
||||||
|
!isa<ConstantFP>(CP->getOperand(i))) {
|
||||||
|
AllSimpleConstants = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all of the elements are simple constants, we can fold this.
|
||||||
|
if (AllSimpleConstants)
|
||||||
|
return CastConstantPacked(const_cast<ConstantPacked*>(CP), DestPTy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConstRules &Rules = ConstRules::get(V, V);
|
ConstRules &Rules = ConstRules::get(V, V);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue