Repository: llvm/llvm-project
File: llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp (C++)

Code before:
    Cmp->setSameSign();
    Changed = true;
  }

  return Changed;
}

/// See if LazyValueInfo's ability to exploit edge conditions or range
/// information is sufficient to prove this comparison. Even for local
/// conditions, this can sometimes prove conditions instcombine can't by
/// exploiting range information.
static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
  Value *Op0 = Cmp->getOperand(0);
  Value *Op1 = Cmp->getOperand(1);
  Constant *Res = LVI->getPredicateAt(Cmp->getPredicate(), Op0, Op1, Cmp,
                                      /*UseBlockValue=*/true);
  if (!Res)
    return false;

  bool Changed = false;
  Cmp->replaceUsesWithIf(Res, [&Changed](Use &U) {
    if (isa<AssumeInst>(U.getUser()))
      return false;
    Changed = true;
    return true;
  });
  if (Cmp->use_empty()) {
    Cmp->eraseFromParent();
    Changed = true;
  }

  if (Changed)
    ++NumCmps;

  return Changed;
}

static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
  if (constantFoldCmp(Cmp, LVI))
    return true;

  if (auto *ICmp = dyn_cast<ICmpInst>(Cmp))
    if (processICmp(ICmp, LVI))
      return true;

  return false;
}

/// Simplify a switch instruction by removing cases which can never fire. If the
/// uselessness of a case could be determined locally then constant propagation
/// would already have figured it out. Instead, walk the predecessors and

Review comment (suggestion):
```suggestion
  bool Changed = Cmp->replaceUsesWithIf(Res, [](Use &U) {
    return !isa<AssumeInst>(U.getUser()));
  });
```
After a rebase on top of https://github.com/llvm/llvm-project/pull/184107.

Code after:
    Cmp->setSameSign();
    Changed = true;
  }

  return Changed;
}

/// See if LazyValueInfo's ability to exploit edge conditions or range
/// information is sufficient to prove this comparison. Even for local
/// conditions, this can sometimes prove conditions instcombine can't by
/// exploiting range information.
static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
  Value *Op0 = Cmp->getOperand(0);
  Value *Op1 = Cmp->getOperand(1);
  Constant *Res = LVI->getPredicateAt(Cmp->getPredicate(), Op0, Op1, Cmp,
                                      /*UseBlockValue=*/true);
  if (!Res)
    return false;

  bool Changed = Cmp->replaceUsesWithIf(
      Res, [](Use &U) { return !isa<AssumeInst>(U.getUser()); });
  if (Cmp->use_empty()) {
    Cmp->eraseFromParent();
    Changed = true;
  }

  if (Changed)
    ++NumCmps;

  return Changed;
}

static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
  if (constantFoldCmp(Cmp, LVI))
    return true;

  if (auto *ICmp = dyn_cast<ICmpInst>(Cmp))
    if (processICmp(ICmp, LVI))
      return true;

  return false;
}

/// Simplify a switch instruction by removing cases which can never fire. If the
/// uselessness of a case could be determined locally then constant propagation
/// would already have figured it out. Instead, walk the predecessors and
/// statically evaluate cases based on information available on that edge. Cases
/// that cannot fire no matter what the incoming edge can safely be removed. If
/// a case fires on every incoming edge then the entire switch can be removed
/// and replaced with a branch to the case destination.
static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,