forked from OSchip/llvm-project
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:
parent
aa4887b482
commit
26feb4f6d8
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue