mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
revert my recent int<->fp and vector union promotion changes, they expose
obscure bugs affecting the X86 code generator. I will reenable this when fixed. llvm-svn: 32524
This commit is contained in:
parent
f72f8a7730
commit
b486de5e73
@ -419,64 +419,39 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) {
|
|||||||
/// types are incompatible, return true, otherwise update Accum and return
|
/// types are incompatible, return true, otherwise update Accum and return
|
||||||
/// false.
|
/// false.
|
||||||
///
|
///
|
||||||
/// There are three cases we handle here:
|
/// There are two cases we handle here:
|
||||||
/// 1) An effectively-integer union, where the pieces are stored into as
|
/// 1) An effectively integer union, where the pieces are stored into as
|
||||||
/// smaller integers (common with byte swap and other idioms).
|
/// smaller integers (common with byte swap and other idioms).
|
||||||
/// 2) A union of vector types of the same size and potentially its elements.
|
/// 2) A union of a vector and its elements. Here we turn element accesses
|
||||||
/// Here we turn element accesses into insert/extract element operations.
|
/// into insert/extract element operations.
|
||||||
/// 3) A union of scalar types, such as int/float or int/pointer. Here we
|
|
||||||
/// merge together into integers, allowing the xform to work with #1 as
|
|
||||||
/// well.
|
|
||||||
static bool MergeInType(const Type *In, const Type *&Accum,
|
static bool MergeInType(const Type *In, const Type *&Accum,
|
||||||
const TargetData &TD) {
|
const TargetData &TD) {
|
||||||
// If this is our first type, just use it.
|
// If this is our first type, just use it.
|
||||||
const PackedType *PTy;
|
const PackedType *PTy;
|
||||||
if (Accum == Type::VoidTy || In == Accum) {
|
if (Accum == Type::VoidTy || In == Accum) {
|
||||||
Accum = In;
|
Accum = In;
|
||||||
} else if (In == Type::VoidTy) {
|
|
||||||
// Noop.
|
|
||||||
} else if (In->isIntegral() && Accum->isIntegral()) { // integer union.
|
} else if (In->isIntegral() && Accum->isIntegral()) { // integer union.
|
||||||
// Otherwise pick whichever type is larger.
|
// Otherwise pick whichever type is larger.
|
||||||
if (In->getTypeID() > Accum->getTypeID())
|
if (In->getTypeID() > Accum->getTypeID())
|
||||||
Accum = In;
|
Accum = In;
|
||||||
} else if (isa<PointerType>(In) && isa<PointerType>(Accum)) {
|
} else if (isa<PointerType>(In) && isa<PointerType>(Accum)) {
|
||||||
// Pointer unions just stay as one of the pointers.
|
// Pointer unions just stay as one of the pointers.
|
||||||
} else if (isa<PackedType>(In) || isa<PackedType>(Accum)) {
|
} else if ((PTy = dyn_cast<PackedType>(Accum)) &&
|
||||||
if ((PTy = dyn_cast<PackedType>(Accum)) &&
|
PTy->getElementType() == In) {
|
||||||
PTy->getElementType() == In) {
|
// Accum is a vector, and we are accessing an element: ok.
|
||||||
// Accum is a vector, and we are accessing an element: ok.
|
} else if ((PTy = dyn_cast<PackedType>(In)) &&
|
||||||
} else if ((PTy = dyn_cast<PackedType>(In)) &&
|
PTy->getElementType() == Accum) {
|
||||||
PTy->getElementType() == Accum) {
|
// In is a vector, and accum is an element: ok, remember In.
|
||||||
// In is a vector, and accum is an element: ok, remember In.
|
Accum = In;
|
||||||
Accum = In;
|
} else if (isa<PointerType>(In) && Accum->isIntegral()) {
|
||||||
} else if ((PTy = dyn_cast<PackedType>(In)) && isa<PackedType>(Accum) &&
|
// Pointer/Integer unions merge together as integers.
|
||||||
PTy->getBitWidth() == cast<PackedType>(Accum)->getBitWidth()) {
|
return MergeInType(TD.getIntPtrType(), Accum, TD);
|
||||||
// Two vectors of the same size: keep Accum.
|
} else if (isa<PointerType>(Accum) && In->isIntegral()) {
|
||||||
} else {
|
// Pointer/Integer unions merge together as integers.
|
||||||
// Cannot insert an short into a <4 x int> or handle
|
Accum = TD.getIntPtrType();
|
||||||
// <2 x int> -> <4 x int>
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Pointer/FP/Integer unions merge together as integers.
|
|
||||||
switch (Accum->getTypeID()) {
|
|
||||||
case Type::PointerTyID: Accum = TD.getIntPtrType(); break;
|
|
||||||
case Type::FloatTyID: Accum = Type::UIntTy; break;
|
|
||||||
case Type::DoubleTyID: Accum = Type::ULongTy; break;
|
|
||||||
default:
|
|
||||||
assert(Accum->isIntegral() && "Unknown FP type!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (In->getTypeID()) {
|
|
||||||
case Type::PointerTyID: In = TD.getIntPtrType(); break;
|
|
||||||
case Type::FloatTyID: In = Type::UIntTy; break;
|
|
||||||
case Type::DoubleTyID: In = Type::ULongTy; break;
|
|
||||||
default:
|
|
||||||
assert(In->isIntegral() && "Unknown FP type!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return MergeInType(In, Accum, TD);
|
return MergeInType(In, Accum, TD);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -518,7 +493,8 @@ const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) {
|
|||||||
|
|
||||||
if (MergeInType(SI->getOperand(0)->getType(), UsedType, TD))
|
if (MergeInType(SI->getOperand(0)->getType(), UsedType, TD))
|
||||||
return 0;
|
return 0;
|
||||||
} else if (BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
|
} else if (CastInst *CI = dyn_cast<CastInst>(User)) {
|
||||||
|
if (!isa<PointerType>(CI->getType())) return 0;
|
||||||
IsNotTrivial = true;
|
IsNotTrivial = true;
|
||||||
const Type *SubTy = CanConvertToScalar(CI, IsNotTrivial);
|
const Type *SubTy = CanConvertToScalar(CI, IsNotTrivial);
|
||||||
if (!SubTy || MergeInType(SubTy, UsedType, TD)) return 0;
|
if (!SubTy || MergeInType(SubTy, UsedType, TD)) return 0;
|
||||||
@ -632,54 +608,24 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) {
|
|||||||
Value *NV = new LoadInst(NewAI, LI->getName(), LI);
|
Value *NV = new LoadInst(NewAI, LI->getName(), LI);
|
||||||
if (NV->getType() != LI->getType()) {
|
if (NV->getType() != LI->getType()) {
|
||||||
if (const PackedType *PTy = dyn_cast<PackedType>(NV->getType())) {
|
if (const PackedType *PTy = dyn_cast<PackedType>(NV->getType())) {
|
||||||
// If the result alloca is a packed type, this is either an element
|
// Must be an element access.
|
||||||
// access or a bitcast to another packed type.
|
unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
|
||||||
if (isa<PackedType>(LI->getType())) {
|
NV = new ExtractElementInst(NV, ConstantInt::get(Type::UIntTy, Elt),
|
||||||
NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
|
"tmp", LI);
|
||||||
} else {
|
|
||||||
// Must be an element access.
|
|
||||||
unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
|
|
||||||
NV = new ExtractElementInst(NV, ConstantInt::get(Type::UIntTy, Elt),
|
|
||||||
"tmp", LI);
|
|
||||||
}
|
|
||||||
} else if (isa<PointerType>(NV->getType())) {
|
|
||||||
assert(isa<PointerType>(LI->getType()));
|
|
||||||
// Must be ptr->ptr cast. Anything else would result in NV being
|
|
||||||
// an integer.
|
|
||||||
NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
|
|
||||||
} else {
|
} else {
|
||||||
assert(NV->getType()->isInteger() && "Unknown promotion!");
|
if (Offset) {
|
||||||
if (Offset && Offset < TD.getTypeSize(NV->getType())*8) {
|
assert(NV->getType()->isInteger() && "Unknown promotion!");
|
||||||
NV = new ShiftInst(Instruction::LShr, NV,
|
if (Offset < TD.getTypeSize(NV->getType())*8) {
|
||||||
ConstantInt::get(Type::UByteTy, Offset),
|
NV = new ShiftInst(Instruction::LShr, NV,
|
||||||
LI->getName(), LI);
|
ConstantInt::get(Type::UByteTy, Offset),
|
||||||
}
|
LI->getName(), LI);
|
||||||
|
|
||||||
// If the result is an integer, this is a trunc or bitcast.
|
|
||||||
if (LI->getType()->isIntegral()) {
|
|
||||||
NV = CastInst::createTruncOrBitCast(NV, LI->getType(),
|
|
||||||
LI->getName(), LI);
|
|
||||||
} else if (LI->getType()->isFloatingPoint()) {
|
|
||||||
// If needed, truncate the integer to the appropriate size.
|
|
||||||
if (NV->getType()->getPrimitiveSize() >
|
|
||||||
LI->getType()->getPrimitiveSize()) {
|
|
||||||
switch (LI->getType()->getTypeID()) {
|
|
||||||
default: assert(0 && "Unknown FP type!");
|
|
||||||
case Type::FloatTyID:
|
|
||||||
NV = new TruncInst(NV, Type::UIntTy, LI->getName(), LI);
|
|
||||||
break;
|
|
||||||
case Type::DoubleTyID:
|
|
||||||
NV = new TruncInst(NV, Type::ULongTy, LI->getName(), LI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then do a bitcast.
|
|
||||||
NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI);
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise must be a pointer.
|
assert((NV->getType()->isInteger() ||
|
||||||
NV = new IntToPtrInst(NV, LI->getType(), LI->getName(), LI);
|
isa<PointerType>(NV->getType())) && "Unknown promotion!");
|
||||||
}
|
}
|
||||||
|
NV = CastInst::createInferredCast(NV, LI->getType(), LI->getName(),
|
||||||
|
LI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LI->replaceAllUsesWith(NV);
|
LI->replaceAllUsesWith(NV);
|
||||||
@ -695,55 +641,30 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) {
|
|||||||
Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
|
Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
|
||||||
|
|
||||||
if (const PackedType *PTy = dyn_cast<PackedType>(AllocaType)) {
|
if (const PackedType *PTy = dyn_cast<PackedType>(AllocaType)) {
|
||||||
// If the result alloca is a packed type, this is either an element
|
// Must be an element insertion.
|
||||||
// access or a bitcast to another packed type.
|
unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
|
||||||
if (isa<PackedType>(SV->getType())) {
|
SV = new InsertElementInst(Old, SV,
|
||||||
SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
|
ConstantInt::get(Type::UIntTy, Elt),
|
||||||
} else {
|
"tmp", SI);
|
||||||
// Must be an element insertion.
|
|
||||||
unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8);
|
|
||||||
SV = new InsertElementInst(Old, SV,
|
|
||||||
ConstantInt::get(Type::UIntTy, Elt),
|
|
||||||
"tmp", SI);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// If SV is a float, convert it to the appropriate integer type.
|
// Always zero extend the value.
|
||||||
// If it is a pointer, do the same, and also handle ptr->ptr casts
|
if (SV->getType()->isSigned())
|
||||||
// here.
|
SV = CastInst::createInferredCast(SV,
|
||||||
switch (SV->getType()->getTypeID()) {
|
SV->getType()->getUnsignedVersion(), SV->getName(), SI);
|
||||||
default:
|
SV = CastInst::createInferredCast(SV, Old->getType(), SV->getName(),
|
||||||
assert(!SV->getType()->isFloatingPoint() && "Unknown FP type!");
|
SI);
|
||||||
break;
|
if (Offset && Offset < TD.getTypeSize(SV->getType())*8)
|
||||||
case Type::FloatTyID:
|
|
||||||
SV = new BitCastInst(SV, Type::UIntTy, SV->getName(), SI);
|
|
||||||
break;
|
|
||||||
case Type::DoubleTyID:
|
|
||||||
SV = new BitCastInst(SV, Type::ULongTy, SV->getName(), SI);
|
|
||||||
break;
|
|
||||||
case Type::PointerTyID:
|
|
||||||
if (isa<PointerType>(AllocaType))
|
|
||||||
SV = new BitCastInst(SV, AllocaType, SV->getName(), SI);
|
|
||||||
else
|
|
||||||
SV = new PtrToIntInst(SV, TD.getIntPtrType(), SV->getName(), SI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned SrcSize = TD.getTypeSize(SV->getType())*8;
|
|
||||||
|
|
||||||
// Always zero extend the value if needed.
|
|
||||||
if (SV->getType() != AllocaType)
|
|
||||||
SV = CastInst::createZExtOrBitCast(SV, AllocaType,
|
|
||||||
SV->getName(), SI);
|
|
||||||
if (Offset && Offset < AllocaType->getPrimitiveSizeInBits())
|
|
||||||
SV = new ShiftInst(Instruction::Shl, SV,
|
SV = new ShiftInst(Instruction::Shl, SV,
|
||||||
ConstantInt::get(Type::UByteTy, Offset),
|
ConstantInt::get(Type::UByteTy, Offset),
|
||||||
SV->getName()+".adj", SI);
|
SV->getName()+".adj", SI);
|
||||||
// Mask out the bits we are about to insert from the old value.
|
// Mask out the bits we are about to insert from the old value.
|
||||||
unsigned TotalBits = TD.getTypeSize(SV->getType())*8;
|
unsigned TotalBits = TD.getTypeSize(SV->getType())*8;
|
||||||
if (TotalBits != SrcSize) {
|
unsigned InsertBits = TD.getTypeSize(SI->getOperand(0)->getType())*8;
|
||||||
assert(TotalBits > SrcSize);
|
if (TotalBits != InsertBits) {
|
||||||
uint64_t Mask = ~(((1ULL << SrcSize)-1) << Offset);
|
assert(TotalBits > InsertBits);
|
||||||
Mask = Mask & SV->getType()->getIntegralTypeMask();
|
uint64_t Mask = ~(((1ULL << InsertBits)-1) << Offset);
|
||||||
|
if (TotalBits != 64)
|
||||||
|
Mask = Mask & ((1ULL << TotalBits)-1);
|
||||||
Old = BinaryOperator::createAnd(Old,
|
Old = BinaryOperator::createAnd(Old,
|
||||||
ConstantInt::get(Old->getType(), Mask),
|
ConstantInt::get(Old->getType(), Mask),
|
||||||
Old->getName()+".mask", SI);
|
Old->getName()+".mask", SI);
|
||||||
|
Loading…
Reference in New Issue
Block a user