Closed
Description
I ended up here from code doing essentially a spaceship operator, then comparing against zero: ((a > b) - (a < b)) <= 0
.
That could optimize away: https://alive2.llvm.org/ce/z/_jFfvV
define i1 @src(i16 %0, i16 %1) noundef {
%start:
%_8.i.i.i = icmp ult i16 %0, %1
%_7.neg.i.i.i = sext i1 %_8.i.i.i to i8
%_12.i.i.i = icmp ugt i16 %0, %1
%_11.i.i.i = zext i1 %_12.i.i.i to i8
%2 = add nsw i8 %_7.neg.i.i.i, %_11.i.i.i
%3 = icmp slt i8 %2, 1
ret i1 %3
}
=>
define i1 @tgt(i16 %0, i16 %1) noundef {
%start:
%x = icmp ule i16 %0, %1
ret i1 %x
}
Transformation seems to be correct!
But today it doesn't: https://llvm.godbolt.org/z/WerxaczEc
Original Rust repro: https://rust.godbolt.org/z/n6b5KWWhG
pub fn spaceship(x: i16, y: i16) -> i8 {
(x > y) as i8 - (x < y) as i8
}
pub fn check_lt(x: i16, y: i16) -> bool {
spaceship(x, y) < 0
}
pub fn check_le(x: i16, y: i16) -> bool {
spaceship(x, y) <= 0
}
pub fn check_gt(x: i16, y: i16) -> bool {
spaceship(x, y) > 0
}
pub fn check_ge(x: i16, y: i16) -> bool {
spaceship(x, y) >= 0
}
Interestingly, check_lt
and check_ge
both optimize down to a single icmp
, exactly as hoped. But neither check_le
nor check_gt
does.