llvm/llvm-project

Missed Optimization: max(max(x, c1) << c2, c3) —> max(x << c2, c3) when c3 >= c1 * 2 ^ c2

Open

#139,786 opened on 2025年5月13日

GitHub で見る
 (11 comments) (0 reactions) (2 assignees)C++ (10,782 forks)batch import
good first issuellvm:instcombinemissed-optimization

Repository metrics

Stars
 (26,378 stars)
PR merge metrics
 (平均マージ 1d 2h) (30d で 1,000 merged PRs)

説明

define i8 @src(i8 %arg0) {
  %1 = call i8 @llvm.umax.i8(i8 %arg0, i8 1)
  %2 = shl nuw i8 %1, 1
  %3 = call i8 @llvm.umax.i8(i8 %2, i8 16)
  %4 = icmp sgt i8 %1, -1
  %5 = select i1 %4, i8 %3, i8 -1
  ret i8 %3
}

define i8 @tgt(i8 %arg0) {
  %1 = shl nuw i8 %arg0, 1
  %2 = call i8 @llvm.umax.i8(i8 %1, i8 16)
  %3 = icmp sgt i8 %2, -1
  %4 = select i1 %3, i8 %2, i8 -1
  ret i8 %2
}

Alive2: https://alive2.llvm.org/ce/z/on2tJE

Found this pattern at: https://github.com/dtcxzyw/llvm-opt-benchmark/blob/94dab89f901fdfae3e47dc6696c06d591fdd7993/bench/openssl/optimized/packet.ll#L1086-L1094

I think this transformation can be generalized to operations other than shift and also to min().

コントリビューターガイド