Skip to content

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

@Cancelll

Description

@Cancelll
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().

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions