Issue 128377
Summary LLVM fails to optimize average round op down to a single average round instruction
Labels new issue
Assignees
Reporter johnplatts
    Here is a snippet of LLVM IR code that LLVM fails to optimize down to an average round instruction on SSE2/AArch64/POWER8 (and other targets with a SIMD average round instruction):
```
define dso_local <16 x i8> @AvgRoundU8x16(<16 x i8> %vec_a, <16 x i8> %vec_b) local_unnamed_addr #0 {
  %vec_a_shr_1 = lshr <16 x i8> %vec_a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %vec_b_shr_1 = lshr <16 x i8> %vec_b, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
 %vec_a_or_vec_b = or <16 x i8> %vec_b, %vec_a
  %vec_a_or_vec_b_lsb = and <16 x i8> %vec_a_or_vec_b, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %sum0 = add <16 x i8> %vec_b_shr_1, %vec_a_shr_1
  %sum1 = add <16 x i8> %sum0, %vec_a_or_vec_b_lsb
  ret <16 x i8> %sum1
}

define dso_local <16 x i8> @AvgRoundI8x16(<16 x i8> %vec_a, <16 x i8> %vec_b) local_unnamed_addr #0 {
 %vec_a_shr_1 = ashr <16 x i8> %vec_a, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %vec_b_shr_1 = ashr <16 x i8> %vec_b, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %vec_a_or_vec_b = or <16 x i8> %vec_b, %vec_a
  %vec_a_or_vec_b_lsb = and <16 x i8> %vec_a_or_vec_b, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %sum0 = add <16 x i8> %vec_b_shr_1, %vec_a_shr_1
  %sum1 = add <16 x i8> %sum0, %vec_a_or_vec_b_lsb
  ret <16 x i8> %sum1
}

define dso_local <8 x i16> @AvgRoundU16x8(<8 x i16> %vec_a, <8 x i16> %vec_b) local_unnamed_addr #0 {
  %vec_a_shr_1 = lshr <8 x i16> %vec_a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %vec_b_shr_1 = lshr <8 x i16> %vec_b, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
 %vec_a_or_vec_b = or <8 x i16> %vec_b, %vec_a
  %vec_a_or_vec_b_lsb = and <8 x i16> %vec_a_or_vec_b, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %sum0 = add <8 x i16> %vec_b_shr_1, %vec_a_shr_1
  %sum1 = add <8 x i16> %sum0, %vec_a_or_vec_b_lsb
  ret <8 x i16> %sum1
}

define dso_local <8 x i16> @AvgRoundI16x8(<8 x i16> %vec_a, <8 x i16> %vec_b) local_unnamed_addr #0 {
  %vec_a_shr_1 = ashr <8 x i16> %vec_a, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %vec_b_shr_1 = ashr <8 x i16> %vec_b, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
 %vec_a_or_vec_b = or <8 x i16> %vec_b, %vec_a
  %vec_a_or_vec_b_lsb = and <8 x i16> %vec_a_or_vec_b, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %sum0 = add <8 x i16> %vec_b_shr_1, %vec_a_shr_1
  %sum1 = add <8 x i16> %sum0, %vec_a_or_vec_b_lsb
  ret <8 x i16> %sum1
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
```

The above LLVM IR snippet being compiled for x86_64, AArch64, and POWER8 can be found over at Compiler Explorer at https://godbolt.org/z/TKrra9ohh.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to