1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[NFC][CVP] processUDivOrURem(): refactor to use ConstantRange::getActiveBits()

As an exhaustive test shows, this logic is fully identical to the old
implementation, with exception of the case where both of the operands
had empty ranges:

```
TEST_F(ConstantRangeTest, CVP_UDiv) {
  unsigned Bits = 4;
  EnumerateConstantRanges(Bits, [&](const ConstantRange &CR0) {
    if(CR0.isEmptySet())
      return;
    EnumerateConstantRanges(Bits, [&](const ConstantRange &CR1) {
      if(CR0.isEmptySet())
        return;

      unsigned MaxActiveBits = 0;
      for (const ConstantRange &CR : {CR0, CR1})
        MaxActiveBits = std::max(MaxActiveBits, CR.getActiveBits());

      ConstantRange OperandRange(Bits, /*isFullSet=*/false);
      for (const ConstantRange &CR : {CR0, CR1})
        OperandRange = OperandRange.unionWith(CR);
      unsigned NewWidth = OperandRange.getUnsignedMax().getActiveBits();

      EXPECT_EQ(MaxActiveBits, NewWidth) << CR0 << " " << CR1;
    });
  });
}
```
This commit is contained in:
Roman Lebedev 2020-09-22 15:34:45 +03:00
parent ebabbd05e9
commit c2fd2cd7a1

View File

@ -633,18 +633,20 @@ static bool processUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) {
// Find the smallest power of two bitwidth that's sufficient to hold Instr's
// operands.
auto OrigWidth = Instr->getType()->getIntegerBitWidth();
ConstantRange OperandRange(OrigWidth, /*isFullSet=*/false);
// What is the smallest bit width that can accomodate the entire value ranges
// of both of the operands?
unsigned MaxActiveBits = 0;
for (Value *Operand : Instr->operands()) {
OperandRange = OperandRange.unionWith(
LVI->getConstantRange(Operand, Instr->getParent()));
ConstantRange CR = LVI->getConstantRange(Operand, Instr->getParent());
MaxActiveBits = std::max(CR.getActiveBits(), MaxActiveBits);
}
// Don't shrink below 8 bits wide.
unsigned NewWidth = std::max<unsigned>(
PowerOf2Ceil(OperandRange.getUnsignedMax().getActiveBits()), 8);
unsigned NewWidth = std::max<unsigned>(PowerOf2Ceil(MaxActiveBits), 8);
// NewWidth might be greater than OrigWidth if OrigWidth is not a power of
// two.
if (NewWidth >= OrigWidth)
if (NewWidth >= Instr->getType()->getIntegerBitWidth())
return false;
++NumUDivs;