folds for icmp-of-sum-of-extended-i1 aren't happening in more complex code · Issue #73417 · llvm/llvm-project (original) (raw)
I'm trying to take advantage of the folds from dd31a3b (cc @bcl5980 ) in Rust's standard library. They're working great for single fields, but in more complex cases they don't seem to be triggering, leaving poor IR.
For example, if I change Rust'd Ord::cmp
for primitives to use the sext + zext
implementation, then I get the following for <
on a rust tuple of (i16, u16)
:
define noundef zeroext i1 @check_lt_direct(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 { start: %lhs.i.i = icmp sgt i16 %0, %2 %rhs.i.i = icmp slt i16 %0, %2 %self1.i.i = zext i1 %lhs.i.i to i8 %rhs2.neg.i.i = sext i1 %rhs.i.i to i8 %diff.i.i = add nsw i8 %rhs2.neg.i.i, %self1.i.i %4 = icmp eq i8 %diff.i.i, 0 %_0.i.i = icmp ult i16 %1, %3 %5 = icmp slt i8 %diff.i.i, 0 %_0.0.i = select i1 %4, i1 %_0.i.i, i1 %5 ret i1 %_0.0.i }
But it could just be (proof: https://alive2.llvm.org/ce/z/4dD_qc)
define noundef zeroext i1 @tgt(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 { start: ; No longer needed %lhs.i.i = icmp sgt i16 %0, %2 ; No longer needed %rhs.i.i = icmp slt i16 %0, %2 ; No longer needed %self1.i.i = zext i1 %lhs.i.i to i8 ; No longer needed %rhs2.neg.i.i = sext i1 %rhs.i.i to i8 ; No longer needed %diff.i.i = add nsw i8 %rhs2.neg.i.i, %self1.i.i %4 = icmp eq i16 %0, %2 %_0.i.i = icmp ult i16 %1, %3 %5 = icmp slt i16 %0, %2 %_0.0.i = select i1 %4, i1 %_0.i.i, i1 %5 ret i1 %_0.0.i }
By replacing those checks against %diff.i.i
with the simplified forms.
A simpler change to just edit the icmp eq i8 %diff.i.i, 0
also works https://alive2.llvm.org/ce/z/gUqUi7
define noundef zeroext i1 @tgt(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 { start: %lhs.i.i = icmp sgt i16 %0, %2 %rhs.i.i = icmp slt i16 %0, %2 %self1.i.i = zext i1 %lhs.i.i to i8 %rhs2.neg.i.i = sext i1 %rhs.i.i to i8 %diff.i.i = add nsw i8 %rhs2.neg.i.i, %self1.i.i %4 = icmp eq i1 %lhs.i.i, %rhs.i.i ; <-- %_0.i.i = icmp ult i16 %1, %3 %5 = icmp slt i8 %diff.i.i, 0 %_0.0.i = select i1 %4, i1 %_0.i.i, i1 %5 ret i1 %_0.0.i }
with the the other existing folds then able to do their magic to get it down to
define noundef zeroext i1 @tgt(i16 noundef %0, i16 noundef %1, i16 noundef %2, i16 noundef %3) unnamed_addr #0 { %rhs.i.i = icmp slt i16 %0, %2 %.not = icmp eq i16 %0, %2 %_0.i.i = icmp ult i16 %1, %3 %_0.0.i = select i1 %.not, i1 %_0.i.i, i1 %rhs.i.i ret i1 %_0.0.i }