Skip to content

Missed Optimization: Consecutive divisions can be merged into one with intermediate multiplication with sext/zext extention #134318

@MaxGraey

Description

@MaxGraey

Similar to #132908 we can replace consecutive divisions with one division and one multiplication even if last two operands are overflowing. To do this, we need to apply a sext or zext for all operands followed by a lowering to the previous width:

fn src(x: i8, y: i8, z: i8) -> i8 {
   x / y / z
}
fn dst(x: i8, y: i8, z: i8) -> i8 {
   let x = x as i16;
   let y = y as i16;
   let z = z as i16;
   (x / (y * z)) as i8
}

Alive2 proof: https://alive2.llvm.org/ce/z/fR5_nU

define i8 @src(i8 %x, i8 %y, i8 %z) {
start:
  %_4 = sdiv i8 %x, %y
  %_0 = sdiv i8 %_4, %z
  ret i8 %_0
}
define i8 @tgt(i8 %x, i8 %y, i8 %z) {
start:
  %_5 = sext i8 %x to i16
  %_7 = sext i8 %y to i16
  %_8 = sext i8 %z to i16
  %_6 = mul nsw i16 %_8, %_7
  %_4 = sdiv i16 %_5, %_6
  %_0 = trunc i16 %_4 to i8
  ret i8 %_0
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions