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@outlook.com>
28 KiB
28 KiB