1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

[InstCombine] rename SimplifyDivRemOfSelect to be clearer, add comments, simplify code; NFCI

There's at least one bug here - this code can fail with vector types (PR34856).
It's also being called for FREM; I'm still trying to understand how that is valid.

llvm-svn: 315127
This commit is contained in:
Sanjay Patel 2017-10-06 23:20:16 +00:00
parent ab48678342
commit 4f6fd5fe68
2 changed files with 20 additions and 20 deletions

View File

@ -277,7 +277,7 @@ public:
Instruction *visitURem(BinaryOperator &I);
Instruction *visitSRem(BinaryOperator &I);
Instruction *visitFRem(BinaryOperator &I);
bool SimplifyDivRemOfSelect(BinaryOperator &I);
bool simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I);
Instruction *commonRemTransforms(BinaryOperator &I);
Instruction *commonIRemTransforms(BinaryOperator &I);
Instruction *commonDivTransforms(BinaryOperator &I);

View File

@ -778,24 +778,23 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
return Changed ? &I : nullptr;
}
/// Try to fold a divide or remainder of a select instruction.
bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
SelectInst *SI = cast<SelectInst>(I.getOperand(1));
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
int NonNullOperand = -1;
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
if (ST->isNullValue())
NonNullOperand = 2;
// div/rem X, (Cond ? Y : 0) -> div/rem X, Y
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
if (ST->isNullValue())
NonNullOperand = 1;
if (NonNullOperand == -1)
/// Fold a divide or remainder with a select instruction divisor when one of the
/// select operands is zero. In that case, we can use the other select operand
/// because div/rem by zero is undefined.
bool InstCombiner::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
SelectInst *SI = dyn_cast<SelectInst>(I.getOperand(1));
if (!SI)
return false;
Value *SelectCond = SI->getOperand(0);
int NonNullOperand;
if (match(SI->getTrueValue(), m_Zero()))
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
NonNullOperand = 2;
else if (match(SI->getFalseValue(), m_Zero()))
// div/rem X, (Cond ? Y : 0) -> div/rem X, Y
NonNullOperand = 1;
else
return false;
// Change the div/rem to use 'Y' instead of the select.
I.setOperand(1, SI->getOperand(NonNullOperand));
@ -808,6 +807,7 @@ bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
// If the select and condition only have a single use, don't bother with this,
// early exit.
Value *SelectCond = SI->getCondition();
if (SI->use_empty() && SelectCond->hasOneUse())
return true;
@ -863,7 +863,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
// Handle cases involving: [su]div X, (select Cond, Y, Z)
// This does not apply for fdiv.
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
if (simplifyDivRemOfSelectWithZeroOp(I))
return &I;
if (Instruction *LHS = dyn_cast<Instruction>(Op0)) {
@ -1458,7 +1458,7 @@ Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) {
}
// Handle cases involving: rem X, (select Cond, Y, Z)
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
if (simplifyDivRemOfSelectWithZeroOp(I))
return &I;
if (isa<Constant>(Op1)) {
@ -1613,7 +1613,7 @@ Instruction *InstCombiner::visitFRem(BinaryOperator &I) {
return replaceInstUsesWith(I, V);
// Handle cases involving: rem X, (select Cond, Y, Z)
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
if (simplifyDivRemOfSelectWithZeroOp(I))
return &I;
return nullptr;