Fix treecc. Also fix a latent bug in emitBinaryConstOperation that would

allow and const, 0 to be incorrectly codegen'd into a rlwinm instruction.

llvm-svn: 17234
This commit is contained in:
Nate Begeman 2004-10-26 03:48:25 +00:00
parent aa4887b482
commit 26feb4f6d8
1 changed files with 45 additions and 63 deletions

View File

@ -341,17 +341,13 @@ namespace {
/// emitBitfieldInsert - return true if we were able to fold the sequence of /// emitBitfieldInsert - return true if we were able to fold the sequence of
/// instructions into a bitfield insert (rlwimi). /// instructions into a bitfield insert (rlwimi).
bool emitBitfieldInsert(MachineBasicBlock *MBB, bool emitBitfieldInsert(User *OpUser, unsigned DestReg);
MachineBasicBlock::iterator IP,
User *OpUser, unsigned DestReg);
/// emitBitfieldExtract - return true if we were able to fold the sequence /// emitBitfieldExtract - return true if we were able to fold the sequence
/// of instructions into a bitfield extract (rlwinm). /// of instructions into a bitfield extract (rlwinm).
bool emitBitfieldExtract(MachineBasicBlock *MBB, bool emitBitfieldExtract(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
BinaryOperator *AndI, Value *Op, User *OpUser, unsigned DestReg);
unsigned Amount, bool isLeftShift,
unsigned DestReg);
/// emitBinaryConstOperation - Used by several functions to emit simple /// emitBinaryConstOperation - Used by several functions to emit simple
/// arithmetic and logical operations with constants on a register rather /// arithmetic and logical operations with constants on a register rather
@ -410,7 +406,8 @@ namespace {
void emitShiftOperation(MachineBasicBlock *MBB, void emitShiftOperation(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
Value *Op, Value *ShiftAmount, bool isLeftShift, Value *Op, Value *ShiftAmount, bool isLeftShift,
const Type *ResultTy, unsigned DestReg); const Type *ResultTy, ShiftInst *SI,
unsigned DestReg);
/// emitSelectOperation - Common code shared between visitSelectInst and the /// emitSelectOperation - Common code shared between visitSelectInst and the
/// constant expression support. /// constant expression support.
@ -2234,9 +2231,7 @@ static bool isInsertShiftHalf(User *OpUser, Instruction **Op1User,
/// 2. or and, shl 6. or and, (shl-and) /// 2. or and, shl 6. or and, (shl-and)
/// 3. or shr, and 7. or (shr-and), and /// 3. or shr, and 7. or (shr-and), and
/// 4. or and, shr 8. or and, (shr-and) /// 4. or and, shr 8. or and, (shr-and)
bool PPC32ISel::emitBitfieldInsert(MachineBasicBlock *MBB, bool PPC32ISel::emitBitfieldInsert(User *OpUser, unsigned DestReg) {
MachineBasicBlock::iterator IP,
User *OpUser, unsigned DestReg) {
// Instructions to skip if we match any of the patterns // Instructions to skip if we match any of the patterns
Instruction *Op0User, *Op1User = 0, *OptAndI = 0, *OrI = 0; Instruction *Op0User, *Op1User = 0, *OptAndI = 0, *OrI = 0;
unsigned TgtMask, InsMask, Amount = 0; unsigned TgtMask, InsMask, Amount = 0;
@ -2288,45 +2283,39 @@ bool PPC32ISel::emitBitfieldInsert(MachineBasicBlock *MBB,
/// rotate left word immediate then and with mask (rlwinm) instruction. /// rotate left word immediate then and with mask (rlwinm) instruction.
bool PPC32ISel::emitBitfieldExtract(MachineBasicBlock *MBB, bool PPC32ISel::emitBitfieldExtract(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
BinaryOperator *BO, Value *Op, User *OpUser, unsigned DestReg) {
unsigned Amount, bool isLeftShift,
unsigned DestReg) {
return false; return false;
if (BO && BO->getOpcode() == Instruction::And) { /*
// Since the powerpc shift instructions are really rotate left, subtract 32 // Instructions to skip if we match any of the patterns
// to simulate a right shift. Instruction *Op0User, *Op1User = 0;
unsigned Rotate = (isLeftShift) ? Amount : 32 - Amount; unsigned ShiftMask, AndMask, Amount = 0;
bool matched = false;
if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->getOperand(1))) { // We require OpUser to be an instruction to continue
unsigned Imm = CI->getRawValue(), MB, ME; Op0User = dyn_cast<Instruction>(OpUser);
// In the case of a left shift or unsigned right shift, be sure to clear if (0 == Op0User)
// any bits that would have been zeroes shifted in from the left or right. return false;
// Usually instcombine will do this for us, but there's no guarantee the
// optimization has been performed already.
//
// Also, take this opportunity to check for the algebraic right shift case
// where the mask would overlap sign bits shifted in from the left. We do
// not want to perform the optimization in that case since we could clear
// bits that should be set. Think of int (x >> 17) & 0x0000FFFF;
unsigned mask = 0xFFFFFFFF;
if (isLeftShift)
Imm &= (mask << Amount);
else if (!isLeftShift && !Op->getType()->isSigned())
Imm &= (mask >> Amount);
else if (((mask << Rotate) & Imm) != 0)
return false;
if (isRunOfOnes(Imm, MB, ME)) { if (isExtractShiftHalf)
unsigned SrcReg = getReg(Op, MBB, IP); if (isExtractAndHalf)
BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(SrcReg) matched = true;
.addImm(Rotate).addImm(MB).addImm(ME);
BO->replaceAllUsesWith(Op->use_back()); if (matched == false && isExtractAndHalf)
SkipList.push_back(BO); if (isExtractShiftHalf)
return true; matched = true;
}
} if (matched == false)
return false;
if (isRunOfOnes(Imm, MB, ME)) {
unsigned SrcReg = getReg(Op, MBB, IP);
BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(SrcReg).addImm(Rotate)
.addImm(MB).addImm(ME);
Op1User->replaceAllUsesWith(Op0User);
SkipList.push_back(BO);
return true;
} }
return false; */
} }
/// emitBinaryConstOperation - Implement simple binary operators for integral /// emitBinaryConstOperation - Implement simple binary operators for integral
@ -2361,7 +2350,7 @@ void PPC32ISel::emitBinaryConstOperation(MachineBasicBlock *MBB,
} }
} }
if (Opcode == 2) { if (Opcode == 2 && !CI->isNullValue()) {
unsigned MB, ME, mask = CI->getRawValue(); unsigned MB, ME, mask = CI->getRawValue();
if (isRunOfOnes(mask, MB, ME)) { if (isRunOfOnes(mask, MB, ME)) {
BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0) BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0)
@ -2467,7 +2456,7 @@ void PPC32ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
// Special case: op Reg, <const int> // Special case: op Reg, <const int>
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1))
if (Class != cLong) { if (Class != cLong) {
if (emitBitfieldInsert(MBB, IP, BO, DestReg)) if (emitBitfieldInsert(BO, DestReg))
return; return;
unsigned Op0r = getReg(Op0, MBB, IP); unsigned Op0r = getReg(Op0, MBB, IP);
@ -2575,7 +2564,7 @@ void PPC32ISel::doMultiplyConst(MachineBasicBlock *MBB,
// If the element size is exactly a power of 2, use a shift to get it. // If the element size is exactly a power of 2, use a shift to get it.
if (unsigned Shift = ExactLog2(CI->getRawValue())) { if (unsigned Shift = ExactLog2(CI->getRawValue())) {
ConstantUInt *ShiftCI = ConstantUInt::get(Type::UByteTy, Shift); ConstantUInt *ShiftCI = ConstantUInt::get(Type::UByteTy, Shift);
emitShiftOperation(MBB, IP, Op0, ShiftCI, true, Op0->getType(), DestReg); emitShiftOperation(MBB, IP, Op0, ShiftCI, true, Op0->getType(), 0, DestReg);
return; return;
} }
@ -2770,7 +2759,7 @@ void PPC32ISel::visitShiftInst(ShiftInst &I) {
MachineBasicBlock::iterator IP = BB->end(); MachineBasicBlock::iterator IP = BB->end();
emitShiftOperation(BB, IP, I.getOperand(0), I.getOperand(1), emitShiftOperation(BB, IP, I.getOperand(0), I.getOperand(1),
I.getOpcode() == Instruction::Shl, I.getType(), I.getOpcode() == Instruction::Shl, I.getType(),
getReg(I)); &I, getReg(I));
} }
/// emitShiftOperation - Common code shared between visitShiftInst and /// emitShiftOperation - Common code shared between visitShiftInst and
@ -2780,7 +2769,7 @@ void PPC32ISel::emitShiftOperation(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP, MachineBasicBlock::iterator IP,
Value *Op, Value *ShiftAmount, Value *Op, Value *ShiftAmount,
bool isLeftShift, const Type *ResultTy, bool isLeftShift, const Type *ResultTy,
unsigned DestReg) { ShiftInst *SI, unsigned DestReg) {
bool isSigned = ResultTy->isSigned (); bool isSigned = ResultTy->isSigned ();
unsigned Class = getClass (ResultTy); unsigned Class = getClass (ResultTy);
@ -2926,16 +2915,8 @@ void PPC32ISel::emitShiftOperation(MachineBasicBlock *MBB,
// If this is a shift with one use, and that use is an And instruction, // If this is a shift with one use, and that use is an And instruction,
// then attempt to emit a bitfield operation. // then attempt to emit a bitfield operation.
User *U = Op->use_back(); if (SI && emitBitfieldInsert(SI, DestReg))
if (U->hasOneUse()) { return;
BinaryOperator *BO = dyn_cast<BinaryOperator>(*(U->use_begin()));
if (BO) {
if (emitBitfieldInsert(MBB, IP, U, DestReg))
return;
if (emitBitfieldExtract(MBB, IP, BO, Op, Amount, isLeftShift, DestReg))
return;
}
}
unsigned SrcReg = getReg (Op, MBB, IP); unsigned SrcReg = getReg (Op, MBB, IP);
if (isLeftShift) { if (isLeftShift) {
@ -3325,7 +3306,8 @@ void PPC32ISel::emitCastOperation(MachineBasicBlock *MBB,
unsigned CallReg = makeAnotherReg(DestTy); unsigned CallReg = makeAnotherReg(DestTy);
unsigned ShiftedReg = makeAnotherReg(SrcTy); unsigned ShiftedReg = makeAnotherReg(SrcTy);
ConstantSInt *Const1 = ConstantSInt::get(Type::IntTy, 1); ConstantSInt *Const1 = ConstantSInt::get(Type::IntTy, 1);
emitShiftOperation(BB, BB->end(), Src, Const1, false, SrcTy, ShiftedReg); emitShiftOperation(BB, BB->end(), Src, Const1, false, SrcTy, 0,
ShiftedReg);
SetArgs.push_back(ValueRecord(ShiftedReg, SrcTy)); SetArgs.push_back(ValueRecord(ShiftedReg, SrcTy));
TheCall = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true); TheCall = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
doCall(ValueRecord(CallReg, DestTy), TheCall, SetArgs, false); doCall(ValueRecord(CallReg, DestTy), TheCall, SetArgs, false);