*Both* operands of divide need sign-extension before divide (if smaller

than machine register size), not just the second operand.

llvm-svn: 7475
This commit is contained in:
Vikram S. Adve 2003-08-01 15:54:38 +00:00
parent 36fcc5d8b3
commit 16c2b62d13
1 changed files with 16 additions and 8 deletions

View File

@ -2053,29 +2053,37 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
// If second operand of divide is smaller than 64 bits, we have // If either operand of divide is smaller than 64 bits, we have
// to make sure the unused top bits are correct because they affect // to make sure the unused top bits are correct because they affect
// the result. These bits are already correct for unsigned values. // the result. These bits are already correct for unsigned values.
// They may be incorrect for signed values, so sign extend to fill in. // They may be incorrect for signed values, so sign extend to fill in.
Instruction* divI = subtreeRoot->getInstruction(); Instruction* divI = subtreeRoot->getInstruction();
Value* divOp1 = subtreeRoot->leftChild()->getValue();
Value* divOp2 = subtreeRoot->rightChild()->getValue(); Value* divOp2 = subtreeRoot->rightChild()->getValue();
Value* divOpToUse = divOp2; Value* divOp1ToUse = divOp1;
if (divOp2->getType()->isSigned()) { Value* divOp2ToUse = divOp2;
unsigned opSize=target.getTargetData().getTypeSize(divOp2->getType()); if (divI->getType()->isSigned()) {
unsigned opSize=target.getTargetData().getTypeSize(divI->getType());
if (opSize < 8) { if (opSize < 8) {
MachineCodeForInstruction& mcfi=MachineCodeForInstruction::get(divI); MachineCodeForInstruction& mcfi=MachineCodeForInstruction::get(divI);
divOpToUse = new TmpInstruction(mcfi, divOp2); divOp1ToUse = new TmpInstruction(mcfi, divOp1);
divOp2ToUse = new TmpInstruction(mcfi, divOp2);
target.getInstrInfo(). target.getInstrInfo().
CreateSignExtensionInstructions(target, CreateSignExtensionInstructions(target,
divI->getParent()->getParent(), divI->getParent()->getParent(),
divOp2, divOpToUse, divOp1, divOp1ToUse,
8*opSize, mvec, mcfi);
target.getInstrInfo().
CreateSignExtensionInstructions(target,
divI->getParent()->getParent(),
divOp2, divOp2ToUse,
8*opSize, mvec, mcfi); 8*opSize, mvec, mcfi);
} }
} }
mvec.push_back(BuildMI(ChooseDivInstruction(target, subtreeRoot), 3) mvec.push_back(BuildMI(ChooseDivInstruction(target, subtreeRoot), 3)
.addReg(subtreeRoot->leftChild()->getValue()) .addReg(divOp1ToUse)
.addReg(divOpToUse) .addReg(divOp2ToUse)
.addRegDef(divI)); .addRegDef(divI));
break; break;