diff options
| author | Nadav Rotem <nrotem@apple.com> | 2015-03-06 00:23:58 +0000 |
|---|---|---|
| committer | Nadav Rotem <nrotem@apple.com> | 2015-03-06 00:23:58 +0000 |
| commit | c99a38796c199b5ea8f6657f3e338ab43466ea6b (patch) | |
| tree | 628648b464c94b35ee034dc79a41a4accfab1a6d /llvm/lib | |
| parent | 25d5abdb3a0584e3f43e6979db37009dbda33521 (diff) | |
| download | bcm5719-llvm-c99a38796c199b5ea8f6657f3e338ab43466ea6b.tar.gz bcm5719-llvm-c99a38796c199b5ea8f6657f3e338ab43466ea6b.zip | |
Teach ComputeNumSignBits about signed reminder.
This optimization a continuation of r231140 that reasoned about signed div.
llvm-svn: 231433
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index d5202664ae5..f28e3f22d39 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1723,7 +1723,7 @@ unsigned ComputeNumSignBits(Value *V, const DataLayout *TD, Tmp = TyBits - U->getOperand(0)->getType()->getScalarSizeInBits(); return ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q) + Tmp; - case Instruction::SDiv: + case Instruction::SDiv: { const APInt *Denominator; // sdiv X, C -> adds log(C) sign bits. if (match(U->getOperand(1), m_APInt(Denominator))) { @@ -1739,6 +1739,32 @@ unsigned ComputeNumSignBits(Value *V, const DataLayout *TD, return std::min(TyBits, NumBits + Denominator->logBase2()); } break; + } + + case Instruction::SRem: { + const APInt *Denominator; + // srem X, C -> we know that the result is within 0..C-1 when C is a + // positive constant and the sign bits are at most TypeBits - log2(C). + if (match(U->getOperand(1), m_APInt(Denominator))) { + + // Ignore non-positive denominator. + if (!Denominator->isStrictlyPositive()) + break; + + // Calculate the incoming numerator bits. SRem by a positive constant + // can't lower the number of sign bits. + unsigned NumrBits = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q); + + // Calculate the leading sign bit constraints by examining the + // denominator. The remainder is in the range 0..C-1, which is + // calculated by the log2(denominator). The sign bits are the bit-width + // minus this value. The result of this subtraction has to be positive. + unsigned ResBits = TyBits - Denominator->logBase2(); + + return std::max(NumrBits, ResBits); + } + break; + } case Instruction::AShr: { Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q); |

