[InstCombine] Reland #165975: Fix #163110: Support peeling off matching shifts from icmp operands via canEvaluateShifted (#190918)
This relanding of #165975 fixes the bug that caused the bootstrap-asan
buildbot failure
(https://lab.llvm.org/buildbot/#/builders/52/builds/16329).
## Original optimization
Consider a pattern like: `icmp (shl nsw/nuw X, L), (add nsw/nuw (shl
nsw/nuw Y, L), K)`
When K is a multiple of 2^L, this can be simplified to: `icmp X, (add
nsw/nuw Y, K >> L)`
This patch extends `canEvaluateShifted` to support `Instruction::Add`
and refactors its signature to accept a `ShiftSemantics` enum (`Lossy` /
`Unsigned` / `Signed`) instead of a bare opcode. This allows the
function to enforce losslessness requirements according to the overflow
flags (nsw/nuw) of the operands. The logic is wired into
`foldICmpCommutative` to fold `icmp (shl nuw/nsw X, C), Op1` into `icmp
X, (Op1 >> C)` when Op1 can be right-shifted losslessly by C bits.
## Bug fixed since #165975
`canEvaluateShiftedShift` unconditionally returned `true` for
same-direction logical shifts, ignoring the `ShiftSemantics` parameter.
This caused `foldICmpCommutative` to incorrectly transform:
`icmp uge (shl nuw X, 4), (lshr Y, 1) → icmp uge X, (lshr Y, 5) ← WRONG`
**Fix:** `canEvaluateShiftedShift` now returns `true` for same-direction
shifts only when `Semantics == ShiftSemantics::Lossy`, blocking the
unsafe fold for `Unsigned`/`Signed` semantics. Regression test added in
`Transforms/InstCombine/icmp_shl_lshr_fold.ll`.