mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Fix a problem that Nate noticed that boils down to an over conservative check
in the code that does "select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y)))". We now compile this loop: LBB1_1: ; no_exit add r6, r2, r3 subf r3, r2, r3 cmpwi cr0, r2, 0 addi r7, r5, 4 lwz r2, 0(r5) addi r4, r4, 1 blt cr0, LBB1_4 ; no_exit LBB1_3: ; no_exit mr r3, r6 LBB1_4: ; no_exit cmpwi cr0, r4, 16 mr r5, r7 bne cr0, LBB1_1 ; no_exit into this instead: LBB1_1: ; no_exit srawi r6, r2, 31 add r2, r2, r6 xor r6, r2, r6 addi r7, r5, 4 lwz r2, 0(r5) addi r4, r4, 1 add r3, r3, r6 cmpwi cr0, r4, 16 mr r5, r7 bne cr0, LBB1_1 ; no_exit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6990600f93
commit
97f37a439c
@ -5074,30 +5074,25 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
||||
}
|
||||
|
||||
if (OtherAddOp) {
|
||||
// So at this point we know we have:
|
||||
// select C, (add X, Y), (sub X, ?)
|
||||
// We can do the transform profitably if either 'Y' = '?' or '?' is
|
||||
// a constant.
|
||||
if (SubOp->getOperand(1) == AddOp ||
|
||||
isa<Constant>(SubOp->getOperand(1))) {
|
||||
Value *NegVal;
|
||||
if (Constant *C = dyn_cast<Constant>(SubOp->getOperand(1))) {
|
||||
NegVal = ConstantExpr::getNeg(C);
|
||||
} else {
|
||||
NegVal = InsertNewInstBefore(
|
||||
BinaryOperator::createNeg(SubOp->getOperand(1)), SI);
|
||||
}
|
||||
|
||||
Value *NewTrueOp = OtherAddOp;
|
||||
Value *NewFalseOp = NegVal;
|
||||
if (AddOp != TI)
|
||||
std::swap(NewTrueOp, NewFalseOp);
|
||||
Instruction *NewSel =
|
||||
new SelectInst(CondVal, NewTrueOp,NewFalseOp,SI.getName()+".p");
|
||||
|
||||
NewSel = InsertNewInstBefore(NewSel, SI);
|
||||
return BinaryOperator::createAdd(SubOp->getOperand(0), NewSel);
|
||||
// So at this point we know we have (Y -> OtherAddOp):
|
||||
// select C, (add X, Y), (sub X, Z)
|
||||
Value *NegVal; // Compute -Z
|
||||
if (Constant *C = dyn_cast<Constant>(SubOp->getOperand(1))) {
|
||||
NegVal = ConstantExpr::getNeg(C);
|
||||
} else {
|
||||
NegVal = InsertNewInstBefore(
|
||||
BinaryOperator::createNeg(SubOp->getOperand(1), "tmp"), SI);
|
||||
}
|
||||
|
||||
Value *NewTrueOp = OtherAddOp;
|
||||
Value *NewFalseOp = NegVal;
|
||||
if (AddOp != TI)
|
||||
std::swap(NewTrueOp, NewFalseOp);
|
||||
Instruction *NewSel =
|
||||
new SelectInst(CondVal, NewTrueOp,NewFalseOp,SI.getName()+".p");
|
||||
|
||||
NewSel = InsertNewInstBefore(NewSel, SI);
|
||||
return BinaryOperator::createAdd(SubOp->getOperand(0), NewSel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user