[all-commits] [llvm/llvm-project] b23f59: [InstCombine] Fold `select (A &/| B), T, F` if `se...

Yingwei Zheng via All-commits all-commits at lists.llvm.org
Sun Dec 31 02:29:02 PST 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: b23f59a646d93c43602b010b997c0b7fc20eef5e
      https://github.com/llvm/llvm-project/commit/b23f59a646d93c43602b010b997c0b7fc20eef5e
  Author: Yingwei Zheng <dtcxzyw2333 at gmail.com>
  Date:   2023-12-31 (Sun, 31 Dec 2023)

  Changed paths:
    M llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    M llvm/test/Transforms/InstCombine/select-and-or.ll
    M llvm/test/Transforms/InstCombine/select-factorize.ll
    M llvm/test/Transforms/InstCombine/zext-or-icmp.ll
    M llvm/test/Transforms/Reassociate/basictest.ll

  Log Message:
  -----------
  [InstCombine] Fold `select (A &/| B), T, F` if `select B, T, F` is foldable (#76621)

This patch does the following folds:
```
(select A && B, T, F) -> (select A, (select B, T, F), F)
(select A || B, T, F) -> (select A, T, (select B, T, F))
```
if `(select B, T, F)` can be folded into a value or a canonicalized SPF.
Alive2: https://alive2.llvm.org/ce/z/4Bdrbu

The original motivation of this patch is to simplify the following
pattern:
```
%.sroa.speculated.i = tail call i64 @llvm.umax.i64(i64 %sub.ptr.div.i.i, i64 1)
%add.i = add i64 %.sroa.speculated.i, %sub.ptr.div.i.i
%cmp7.i = icmp ult i64 %add.i, %sub.ptr.div.i.i
%cmp9.i = icmp ugt i64 %add.i, 1152921504606846975
%or.cond.i = or i1 %cmp7.i, %cmp9.i
%cond.i = select i1 %or.cond.i, i64 1152921504606846975, i64 %add.i
->
%.sroa.speculated.i = tail call i64 @llvm.umax.i64(i64 %sub.ptr.div.i.i, i64 1)
%add.i = add i64 %.sroa.speculated.i, %sub.ptr.div.i.i
%cmp7.i = icmp ult i64 %add.i, %sub.ptr.div.i.i
%max = call i64 @llvm.umax.i64(i64 %add.i, 1152921504606846975)
%cond.i = select i1 %cmp7.i, i64 1152921504606846975, i64 %max
```
The later form has a better codegen for some backends. It is also more
analysis-friendly than the original one.
Godbolt: https://godbolt.org/z/eK6eb5jf1
Alive2: https://alive2.llvm.org/ce/z/VHlxL2

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=7c71d3996a72b9b024622f23bf556539b961c88c&to=638ce8666fadaca1ab2639a3c2bc52a4a8508f40&stat=instructions:u

|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|+0.02%|-0.00%|+0.02%|-0.03%|-0.00%|-0.05%|-0.00%|

It is an alternative to #76203 and #76363 because we can simplify
`select (icmp eq/ne a, b), a, b` into `b` or `a`.
Fixes #75784.
Fixes #76043.

Thank @XChy for providing additional tests.
Co-authored-by: XChy <xxs_chy at outlook.com>




More information about the All-commits mailing list