Open
Description
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
}