llvm.org GIT mirror
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209973 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 6 years ago
2 changed file(s) with 35 addition(s) and 8 deletion(s).
 1367 1367 Value *Reassociate::OptimizeAdd(Instruction *I, 1368 1368 SmallVectorImpl &Ops) { 1369 1369 // Scan the operand lists looking for X and -X pairs. If we find any, we 1370 // can simplify the expression. X+-X == 0. While we're at it, scan for any⏎ 1370 // can simplify expressions like X+-X == 0 and X+~X ==-1. While we're at it,⏎ 1371 // scan for any 1371 1372 // duplicates. We want to canonicalize Y+Y+Y+Z -> 3*Y+Z. 1372 // 1373 // TODO: We could handle "X + ~X" -> "-1" if we wanted, since "-X = ~X+1". 1374 //⏎ 1373 ⏎ 1375 1374 for (unsigned i = 0, e = Ops.size(); i != e; ++i) { 1376 1375 Value *TheOp = Ops[i].Op; 1377 1376 // Check to see if we've seen this operand before. If so, we factor all 1411 1410 continue; 1412 1411 } 1413 1412 1414 // Check for X and -X in the operand list. 1415 if (!BinaryOperator::isNeg(TheOp))⏎ 1413 // Check for X and -X or X and ~X in the operand list.⏎ 1414 if (!BinaryOperator::isNeg(TheOp) && !BinaryOperator::isNot(TheOp)) 1416 1415 continue; 1417 1416 1418 Value *X = BinaryOperator::getNegArgument(TheOp);⏎ 1417 Value *X = nullptr;⏎ 1418 if (BinaryOperator::isNeg(TheOp)) 1419 X = BinaryOperator::getNegArgument(TheOp); 1420 else if (BinaryOperator::isNot(TheOp)) 1421 X = BinaryOperator::getNotArgument(TheOp); 1422 1419 1423 unsigned FoundX = FindInOperandList(Ops, i, X); 1420 1424 if (FoundX == i) 1421 1425 continue; 1422 1426 1423 1427 // Remove X and -X from the operand list. 1424 if (Ops.size() == 2)⏎ 1428 if (Ops.size() == 2 && BinaryOperator::isNeg(TheOp))⏎ 1425 1429 return Constant::getNullValue(X->getType()); 1430 1431 // Remove X and ~X from the operand list. 1432 if (Ops.size() == 2 && BinaryOperator::isNot(TheOp)) 1433 return Constant::getAllOnesValue(X->getType()); 1426 1434 1427 1435 Ops.erase(Ops.begin()+i); 1428 1436 if (i < FoundX) 1433 1441 ++NumAnnihil; 1434 1442 --i; // Revisit element. 1435 1443 e -= 2; // Removed two elements. 1444 1445 // if X and ~X we append -1 to the operand list. 1446 if (BinaryOperator::isNot(TheOp)) { 1447 Value *V = Constant::getAllOnesValue(X->getType()); 1448 Ops.insert(Ops.end(), ValueEntry(getRank(V), V)); 1449 e += 1; 1450 } 1436 1451 } 1437 1452 1438 1453 // Scan the operand list, checking to see if there are any common factors
 31 31 ; CHECK: %tmp.5 = add i32 %b, 1234 32 32 ; CHECK: ret i32 %tmp.5 33 33 } 34 35 define i32 @test4(i32 %b, i32 %a) { 36 %tmp.1 = add i32 %a, 1234 37 %tmp.2 = add i32 %b, %tmp.1 38 %tmp.4 = xor i32 %a, -1 39 ; (b+(a+1234))+~a -> b+1233 40 %tmp.5 = add i32 %tmp.2, %tmp.4 41 ret i32 %tmp.5 42 ; CHECK-LABEL: @test4( 43 ; CHECK: %tmp.5 = add i32 %b, 1233 44 ; CHECK: ret i32 %tmp.5 45 }