Issue 166579
Summary [InstCombine] `llvm.ucmp` recognition/optimization issues
Labels new issue
Assignees
Reporter s-barannikov
    https://gcc.godbolt.org/z/7nT7PMs93

```c
int cmp1(unsigned x, unsigned y) {
    if (x != y)
        return x < y ? -1 : x > y;
    return 42;
}

int cmp2(unsigned x, unsigned y) {
    if (x != y)
        return x < y ? -1 : 1;
    return 42;
}
```

`cmp2` is equivalent to `cmp1`, but `llvm.ucmp` is only recognized in `cmp1`:

```llvm
define dso_local noundef range(i32 -1, 43) i32 @cmp1(unsigned int, unsigned int)(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
  %3 = icmp eq i32 %0, %1
  %4 = tail call i32 @llvm.ucmp.i32.i32(i32 %0, i32 %1)
  %5 = select i1 %3, i32 42, i32 %4
 ret i32 %5
}

define dso_local noundef range(i32 -1, 43) i32 @cmp2(unsigned int, unsigned int)(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
  %3 = icmp eq i32 %0, %1
  %4 = icmp ult i32 %0, %1
  %5 = select i1 %4, i32 -1, i32 1
  %6 = select i1 %3, i32 42, i32 %5
 ret i32 %6
}
```

---

```c
int cmp3(unsigned x, unsigned y) {
 if (x != y)
        return x < y ? -1 : x > y;
    return 0;
}

int cmp4(unsigned x, unsigned y) {
    if (x != y)
        return x < y ? -1 : 1;
    return 0;
}
```

These are both "canonical" `llvm.ucmp`, but `cmp3` contains a redundant `select`:

```llvm
define dso_local noundef range(i32 -1, 2) i32 @cmp3(unsigned int, unsigned int)(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
  %3 = icmp eq i32 %0, %1
  %4 = tail call i32 @llvm.ucmp.i32.i32(i32 %0, i32 %1)
  %5 = select i1 %3, i32 0, i32 %4
  ret i32 %5
}

define dso_local noundef range(i32 -1, 2) i32 @cmp4(unsigned int, unsigned int)(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 {
  %3 = tail call i32 @llvm.ucmp.i32.i32(i32 %0, i32 %1)
  ret i32 %3
}
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to