llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.4k stars 11.74k forks source link

[InstCombine] Missed optimization for `(a + 1) - b == 1` --> `a == b` #72512

Open XChy opened 10 months ago

XChy commented 10 months ago

Alive2 proof: https://alive2.llvm.org/ce/z/EP9iNx Missed example: https://godbolt.org/z/5Wxaxv6s4

Description:

As the title and the example suggests. But to my surprise, LLVM works well on the more general form (a + c) - b == c --> a == b. However, when replacing c with 1, it fails.

Real-world motivation:

This snippet of IR is derived from FFmpeg/.../extr_a64multienc.c_render_charset.c (after O3 pipeline). The example above is a reduced version. If you're interested in the original suboptimal IR and optimal IR, please contact me to get them (I don't attach them because they contain more than 1k lines).

Let me know if you can confirm that it's an optimization opportunity, thanks.

XChy commented 10 months ago

Not just for 1, LLVM missed such optimization for every specific constant integer: https://godbolt.org/z/Mqbb14G7e

dtcxzyw commented 10 months ago

But to my surprise, LLVM works well on the more general form (a + c) - b == c --> a == b. However, when replacing c with 1, it fails.

It looks like a coincidence :( https://godbolt.org/z/xdbscP1bh

sun-jacobi commented 9 months ago

Hi, can I work on this issue ? @XChy @dtcxzyw

XChy commented 9 months ago

Hi, can I work on this issue ? @XChy @dtcxzyw

Thanks for contribution. FYI, InstCombine doesn't handle pattern like (a + c) - b == c -> a - b == 0 in fact. For non-constant operand c, reassociate transforms (a + c) - b == c to (a - b) + c == c, which InstCombine catches in coincidence. So a more general way to solve it may be to check whether LHS and RHS share common value and eliminate it.