@@ -885,23 +885,32 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
885
885
mir:: BinOp :: Cmp => {
886
886
use std:: cmp:: Ordering ;
887
887
debug_assert ! ( !is_float) ;
888
- // FIXME: To avoid this PR changing behaviour, the operations used
889
- // here are those from <https://github.com/rust-lang/rust/pull/63767>,
890
- // as tested by `tests/codegen/integer-cmp.rs`.
891
- // Something in future might want to pick different ones. For example,
892
- // maybe the ones from Clang's `<=>` operator in C++20 (see
893
- // <https://github.com/llvm/llvm-project/issues/60012>) or once we
894
- // update to new LLVM, something to take advantage of the new folds in
895
- // <https://github.com/llvm/llvm-project/issues/59666>.
896
888
let pred = |op| base:: bin_op_to_icmp_predicate ( op, is_signed) ;
897
- let is_lt = bx. icmp ( pred ( hir:: BinOpKind :: Lt ) , lhs, rhs) ;
898
- let is_ne = bx. icmp ( pred ( hir:: BinOpKind :: Ne ) , lhs, rhs) ;
899
- let ge = bx. select (
900
- is_ne,
901
- bx. cx ( ) . const_i8 ( Ordering :: Greater as i8 ) ,
902
- bx. cx ( ) . const_i8 ( Ordering :: Equal as i8 ) ,
903
- ) ;
904
- bx. select ( is_lt, bx. cx ( ) . const_i8 ( Ordering :: Less as i8 ) , ge)
889
+ if bx. cx ( ) . tcx ( ) . sess . opts . optimize == OptLevel :: No {
890
+ // FIXME: This actually generates tighter assembly, and is a classic trick
891
+ // <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>
892
+ // However, as of 2023-11 it optimizes worse in things like derived
893
+ // `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
894
+ // better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
895
+ // be worth trying it in optimized builds as well.
896
+ let is_gt = bx. icmp ( pred ( hir:: BinOpKind :: Gt ) , lhs, rhs) ;
897
+ let gtext = bx. zext ( is_gt, bx. type_i8 ( ) ) ;
898
+ let is_lt = bx. icmp ( pred ( hir:: BinOpKind :: Lt ) , lhs, rhs) ;
899
+ let ltext = bx. zext ( is_lt, bx. type_i8 ( ) ) ;
900
+ bx. unchecked_ssub ( gtext, ltext)
901
+ } else {
902
+ // These operations are those expected by `tests/codegen/integer-cmp.rs`,
903
+ // from <https://github.com/rust-lang/rust/pull/63767>.
904
+ let pred = |op| base:: bin_op_to_icmp_predicate ( op, is_signed) ;
905
+ let is_lt = bx. icmp ( pred ( hir:: BinOpKind :: Lt ) , lhs, rhs) ;
906
+ let is_ne = bx. icmp ( pred ( hir:: BinOpKind :: Ne ) , lhs, rhs) ;
907
+ let ge = bx. select (
908
+ is_ne,
909
+ bx. cx ( ) . const_i8 ( Ordering :: Greater as i8 ) ,
910
+ bx. cx ( ) . const_i8 ( Ordering :: Equal as i8 ) ,
911
+ ) ;
912
+ bx. select ( is_lt, bx. cx ( ) . const_i8 ( Ordering :: Less as i8 ) , ge)
913
+ }
905
914
}
906
915
}
907
916
}
0 commit comments