The output of intrinsic functions like ctpop, cttz, ctlz have limited range from 0 to bitwidth. So if the truncate destination type can hold the source bitwidth size, we can just ignore the truncate and use the truncate src to do combination.
Alive2 proofs:
https://alive2.llvm.org/ce/z/9D_-qP
Imo it makes more sense to do this generically.
(icmp P (trunc(X), C)) if KnownBits(X)[OrigWidth:TruncWidth] == 0 just drop the truncate. That will cover all these intrins + any other cases that happen to come up.