mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[Reassociate] Similar to "X + -X" -> "0", added code to handle "X + ~X" -> "-1".
Handle "X + ~X" -> "-1" in the function Value *Reassociate::OptimizeAdd(Instruction *I, SmallVectorImpl<ValueEntry> &Ops); This patch implements: TODO: We could handle "X + ~X" -> "-1" if we wanted, since "-X = ~X+1". Patch by Rahul Jain! Differential Revision: http://reviews.llvm.org/D3835 llvm-svn: 209973
This commit is contained in:
parent
ff3cea9ab5
commit
9a25b19dba
@ -1368,11 +1368,10 @@ Value *Reassociate::OptimizeXor(Instruction *I,
|
|||||||
Value *Reassociate::OptimizeAdd(Instruction *I,
|
Value *Reassociate::OptimizeAdd(Instruction *I,
|
||||||
SmallVectorImpl<ValueEntry> &Ops) {
|
SmallVectorImpl<ValueEntry> &Ops) {
|
||||||
// Scan the operand lists looking for X and -X pairs. If we find any, we
|
// Scan the operand lists looking for X and -X pairs. If we find any, we
|
||||||
// can simplify the expression. X+-X == 0. While we're at it, scan for any
|
// can simplify expressions like X+-X == 0 and X+~X ==-1. While we're at it,
|
||||||
|
// scan for any
|
||||||
// duplicates. We want to canonicalize Y+Y+Y+Z -> 3*Y+Z.
|
// duplicates. We want to canonicalize Y+Y+Y+Z -> 3*Y+Z.
|
||||||
//
|
|
||||||
// TODO: We could handle "X + ~X" -> "-1" if we wanted, since "-X = ~X+1".
|
|
||||||
//
|
|
||||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
|
||||||
Value *TheOp = Ops[i].Op;
|
Value *TheOp = Ops[i].Op;
|
||||||
// Check to see if we've seen this operand before. If so, we factor all
|
// Check to see if we've seen this operand before. If so, we factor all
|
||||||
@ -1412,19 +1411,28 @@ Value *Reassociate::OptimizeAdd(Instruction *I,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for X and -X in the operand list.
|
// Check for X and -X or X and ~X in the operand list.
|
||||||
if (!BinaryOperator::isNeg(TheOp))
|
if (!BinaryOperator::isNeg(TheOp) && !BinaryOperator::isNot(TheOp))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value *X = BinaryOperator::getNegArgument(TheOp);
|
Value *X = nullptr;
|
||||||
|
if (BinaryOperator::isNeg(TheOp))
|
||||||
|
X = BinaryOperator::getNegArgument(TheOp);
|
||||||
|
else if (BinaryOperator::isNot(TheOp))
|
||||||
|
X = BinaryOperator::getNotArgument(TheOp);
|
||||||
|
|
||||||
unsigned FoundX = FindInOperandList(Ops, i, X);
|
unsigned FoundX = FindInOperandList(Ops, i, X);
|
||||||
if (FoundX == i)
|
if (FoundX == i)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remove X and -X from the operand list.
|
// Remove X and -X from the operand list.
|
||||||
if (Ops.size() == 2)
|
if (Ops.size() == 2 && BinaryOperator::isNeg(TheOp))
|
||||||
return Constant::getNullValue(X->getType());
|
return Constant::getNullValue(X->getType());
|
||||||
|
|
||||||
|
// Remove X and ~X from the operand list.
|
||||||
|
if (Ops.size() == 2 && BinaryOperator::isNot(TheOp))
|
||||||
|
return Constant::getAllOnesValue(X->getType());
|
||||||
|
|
||||||
Ops.erase(Ops.begin()+i);
|
Ops.erase(Ops.begin()+i);
|
||||||
if (i < FoundX)
|
if (i < FoundX)
|
||||||
--FoundX;
|
--FoundX;
|
||||||
@ -1434,6 +1442,13 @@ Value *Reassociate::OptimizeAdd(Instruction *I,
|
|||||||
++NumAnnihil;
|
++NumAnnihil;
|
||||||
--i; // Revisit element.
|
--i; // Revisit element.
|
||||||
e -= 2; // Removed two elements.
|
e -= 2; // Removed two elements.
|
||||||
|
|
||||||
|
// if X and ~X we append -1 to the operand list.
|
||||||
|
if (BinaryOperator::isNot(TheOp)) {
|
||||||
|
Value *V = Constant::getAllOnesValue(X->getType());
|
||||||
|
Ops.insert(Ops.end(), ValueEntry(getRank(V), V));
|
||||||
|
e += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the operand list, checking to see if there are any common factors
|
// Scan the operand list, checking to see if there are any common factors
|
||||||
|
@ -32,3 +32,15 @@ define i32 @test3(i32 %b, i32 %a) {
|
|||||||
; CHECK: %tmp.5 = add i32 %b, 1234
|
; CHECK: %tmp.5 = add i32 %b, 1234
|
||||||
; CHECK: ret i32 %tmp.5
|
; CHECK: ret i32 %tmp.5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32 @test4(i32 %b, i32 %a) {
|
||||||
|
%tmp.1 = add i32 %a, 1234
|
||||||
|
%tmp.2 = add i32 %b, %tmp.1
|
||||||
|
%tmp.4 = xor i32 %a, -1
|
||||||
|
; (b+(a+1234))+~a -> b+1233
|
||||||
|
%tmp.5 = add i32 %tmp.2, %tmp.4
|
||||||
|
ret i32 %tmp.5
|
||||||
|
; CHECK-LABEL: @test4(
|
||||||
|
; CHECK: %tmp.5 = add i32 %b, 1233
|
||||||
|
; CHECK: ret i32 %tmp.5
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user