Skip to content

[DivRemPairs] Missed optimization when remainder is "folded" into icmp #168749

@s-barannikov

Description

@s-barannikov

https://gcc.godbolt.org/z/G13GK4M1c

define i8 @src1(i8 noundef %n, i8 noundef %c) {
  %div = udiv i8 %n, %c
  %mul = mul i8 %div, %c
  %rem = sub i8 %n, %mul
  %cmp1 = icmp eq i8 %rem, 0
  %cmp2 = icmp ult i8 %div, %c
  %cond = select i1 %cmp1, i8 42, i8 24
  %retval = select i1 %cmp2, i8 %n, i8 %cond
  ret i8 %retval
}

define i8 @src2(i8 noundef %n, i8 noundef %c) {
  %div = udiv i8 %n, %c
  %mul = mul i8 %div, %c
  %cmp1 = icmp eq i8 %n, %mul ; %rem folded into %cmp1
  %cmp2 = icmp ult i8 %div, %c
  %cond = select i1 %cmp1, i8 42, i8 24
  %retval = select i1 %cmp2, i8 %n, i8 %cond
  ret i8 %retval
}

The difference between the two functions is that in the second one %rem is "folded" into %cmp1 = icmp eq.
It could be optimized as well: https://alive2.llvm.org/ce/z/P_pFDU

The pattern is found in libc++:

if (n == q * p)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions