-- Use size of pointer element type instead of pointer type in array offsets!

-- A few bug fixes in casting between floats and ints.
-- Use SRL reg, 0 instead of AND reg, 0xffffffff to clear high 32 bits.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3579 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-09-05 18:32:13 +00:00
parent 537a877998
commit babc0fab19

View File

@ -319,6 +319,20 @@ CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal)
// CreateCodeToConvertFloatToInt: Convert FP value to signed or unsigned integer
// The FP value must be converted to the dest type in an FP register,
// and the result is then copied from FP to int register via memory.
//
// Since fdtoi converts to signed integers, any FP value V between MAXINT+1
// and MAXUNSIGNED (i.e., 2^31 <= V <= 2^32-1) would be converted incorrectly
// *only* when converting to an unsigned int. (Unsigned byte, short or long
// don't have this problem.)
// For unsigned int, we therefore have to generate the code sequence:
//
// if (V > (float) MAXINT) {
// unsigned result = (unsigned) (V - (float) MAXINT);
// result = result + (unsigned) MAXINT;
// }
// else
// result = (unsigned int) V;
//
static void
CreateCodeToConvertFloatToInt(const TargetMachine& target,
Value* opVal,
@ -331,9 +345,9 @@ CreateCodeToConvertFloatToInt(const TargetMachine& target,
// depends on the type of FP register to use: single-prec for a 32-bit
// int or smaller; double-prec for a 64-bit int.
//
const Type* destTypeToUse = (destI->getType() == Type::LongTy)? Type::DoubleTy
: Type::FloatTy;
Value* destForCast = new TmpInstruction(destTypeToUse, opVal);
size_t destSize = target.DataLayout.getTypeSize(destI->getType());
const Type* destTypeToUse = (destSize > 4)? Type::DoubleTy : Type::FloatTy;
TmpInstruction* destForCast = new TmpInstruction(destTypeToUse, opVal);
mcfi.addTemp(destForCast);
// Create the fp-to-int conversion code
@ -344,7 +358,7 @@ CreateCodeToConvertFloatToInt(const TargetMachine& target,
// Create the fpreg-to-intreg copy code
target.getInstrInfo().
CreateCodeToCopyFloatToInt(target, destI->getParent()->getParent(),
(TmpInstruction*)destForCast, destI, mvec, mcfi);
destForCast, destI, mvec, mcfi);
}
@ -990,28 +1004,34 @@ SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
// offset. (An extra leading zero offset, if any, can be ignored.)
// Generate code sequence to compute address from index.
//
assert(idxVec.size() == 1U + IsZero(idxVec[0])
bool firstIdxIsZero = IsZero(idxVec[0]);
assert(idxVec.size() == 1U + firstIdxIsZero
&& "Array refs must be lowered before Instruction Selection");
Value* idxVal = idxVec[IsZero(idxVec[0])];
Value* idxVal = idxVec[firstIdxIsZero];
assert(! isa<Constant>(idxVal) && "Need to sign-extend uint to 64b!");
vector<MachineInstr*> mulVec;
Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
MachineCodeForInstruction::get(memInst).addTemp(addr);
// Get the array type indexed by idxVal, and compute its element size.
// The call to getTypeSize() will fail if size is not constant.
unsigned int eltSize =
target.DataLayout.getTypeSize(ptrType->getElementType());
assert(eltSize > 0 && "Invalid or non-const array element size");
ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
const Type* vecType = (firstIdxIsZero
? GetElementPtrInst::getIndexedType(ptrType,
std::vector<Value*>(1U, idxVec[0]),
/*AllowCompositeLeaf*/ true)
: ptrType);
const Type* eltType = cast<SequentialType>(vecType)->getElementType();
ConstantUInt* eltSizeVal = ConstantUInt::get(Type::UIntTy,
target.DataLayout.getTypeSize(eltType));
// CreateMulInstruction() folds constants intelligently enough.
CreateMulInstruction(target,
memInst->getParent()->getParent(),
idxVal, /* lval, not likely const */
eltVal, /* rval, likely constant */
addr, /* result*/
idxVal, /* lval, not likely to be const*/
eltSizeVal, /* rval, likely to be constant */
addr, /* result */
mulVec,
MachineCodeForInstruction::get(memInst),
INVALID_MACHINE_OPCODE);
@ -1531,11 +1551,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
case 31: // reg: ToFloatTy(reg):
case 32: // reg: ToDoubleTy(reg):
case 232: // reg: ToDoubleTy(Constant):
// If this instruction has a parent (a user) in the tree
// and the user is translated as an FsMULd instruction,
// then the cast is unnecessary. So check that first.
@ -1572,18 +1592,18 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// register used: single-prec for a 32-bit int or smaller,
// double-prec for a 64-bit int.
//
const Type* srcTypeToUse =
(leftVal->getType() == Type::LongTy)? Type::DoubleTy
: Type::FloatTy;
srcForCast = new TmpInstruction(srcTypeToUse, dest);
uint64_t srcSize =
target.DataLayout.getTypeSize(leftVal->getType());
Type* tmpTypeToUse =
(srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
srcForCast = new TmpInstruction(tmpTypeToUse, dest);
MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest);
destMCFI.addTemp(srcForCast);
target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
dest->getParent()->getParent(),
leftVal, (TmpInstruction*) srcForCast,
leftVal, cast<Instruction>(srcForCast),
mvec, destMCFI);
}
else
@ -2150,7 +2170,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
if (dest->getType()->isUnsigned())
{
unsigned destSize = target.DataLayout.getTypeSize(dest->getType());
if (destSize < target.DataLayout.getIntegerRegize())
if (destSize <= 4)
{ // Mask high bits. Use a TmpInstruction to represent the
// intermediate result before masking. Since those instructions
// have already been generated, go back and substitute tmpI
@ -2162,12 +2182,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
for (unsigned i=0, N=mvec.size(); i < N; ++i)
mvec[i]->substituteValue(dest, tmpI);
M = Create3OperandInstr(AND, tmpI,
ConstantUInt::get(Type::ULongTy,
((uint64_t) 1 << 8*destSize) - 1),
dest);
M = Create3OperandInstr_UImmed(SRL, tmpI, 4-destSize, dest);
mvec.push_back(M);
}
else if (destSize < target.DataLayout.getIntegerRegize())
assert(0 && "Unsupported type size: 32 < size < 64 bits");
}
}
}