derived PartialOrd::le
is non-optimal for 2-field struct of primitive integers · Issue #106107 · rust-lang/rust (original) (raw)
This codegen test should pass: comparison-operators-twofields.patch https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=4c8846efffd0574ec44e60c3cffbe842
And it turns out that the derived PartialOrd::lt
does pass that test
define noundef zeroext i1 @check_lt(i16 %0, i16 %1, i16 %2, i16 %3) unnamed_addr #0 { start: %_6.i.i = icmp slt i16 %0, %2 %_9.i.i.not = icmp eq i16 %0, %2 %_6.i3.i = icmp ult i16 %1, %3 %4 = select i1 %_9.i.i.not, i1 %_6.i3.i, i1 %_6.i.i ret i1 %4 }
but the derived le
, gt
, and ge
do not pass it.
define noundef zeroext i1 @check_gt(i16 %0, i16 %1, i16 %2, i16 %3) unnamed_addr #0 { start: %_6.i.i = icmp slt i16 %0, %2 %_9.i.i = icmp ne i16 %0, %2 %..i.i = zext i1 %_9.i.i to i8 %_3.0.i.i = select i1 %_6.i.i, i8 -1, i8 %..i.i %4 = icmp eq i8 %_3.0.i.i, 0 %_6.i3.i = icmp ult i16 %1, %3 %_9.i4.i = icmp ne i16 %1, %3 %..i5.i = zext i1 %_9.i4.i to i8 %_3.0.i6.i = select i1 %_6.i3.i, i8 -1, i8 %..i5.i %.0.i = select i1 %4, i8 %_3.0.i6.i, i8 %_3.0.i.i %5 = icmp eq i8 %.0.i, 1 ret i1 %5 }
instead leaving in a whole bunch of unnecessary stuff.
Given the direction in #98655, we probably don't want to fix this by changing the derive.
So potential fixes could be changing our Ord::cmp
implementation for integers (cc #105840), changing the default PartialOrd::le
implementations (cc #106065), improved optimizations in LLVM (cc llvm/llvm-project#59666), or more.