[llvm] [DAG] SelectionDAG::canCreateUndefOrPoison - Mark AVGFLOORS and AVGCEILS as safe (PR #148191)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 14 02:21:12 PDT 2025


================
@@ -0,0 +1,16 @@
+; RUN: llc < %s -march=arm64 -mcpu=apple-m1 | FileCheck %s
+
+; CHECK-LABEL: avg:
+; CHECK:       add
+; CHECK:       lsr
+; CHECK:       ret
+
+define zeroext i8 @avg(i8 noundef zeroext %a, i8 noundef zeroext %b) {
+entry:
+  %conv = zext i8 %a to i16
+  %conv1 = zext i8 %b to i16
+  %add = add nuw nsw i16 %conv1, %conv
+  %div3 = lshr i16 %add, 1
+  %conv2 = trunc nuw i16 %div3 to i8
+  ret i8 %conv2
+}
----------------
RKSimon wrote:

What I had in mind was something like this:
```ll
define <8 x i16> @src(<8 x i16> %a0, <8 x i16> %a1) {
  %m0 = and <8 x i16> %a0, splat (i16 15)
  %m1 = and <8 x i16> %a1, splat (i16 15)
  %avg = call <8 x i16> @llvm.aarch64.neon.uhadd.v8i16(<8 x i16> %m0, <8 x i16> %m1)
  %frozen = freeze <8 x i16> %avg
  %mask = and <8 x i16> %frozen, splat (i16 31)
  ret <8 x i16> %mask
}
define <8 x i16> @tgt(<8 x i16> %a0, <8 x i16> %a1) {
  %f0 = freeze <8 x i16> %a0
  %f1 = freeze <8 x i16> %a1
  %m0 = and <8 x i16> %f0, splat (i16 15)
  %m1 = and <8 x i16> %f1, splat (i16 15)
  %avg = call <8 x i16> @llvm.aarch64.neon.uhadd.v8i16(<8 x i16> %m0, <8 x i16> %m1)
  %mask = and <8 x i16> %avg, splat (i16 31)
  ret <8 x i16> %mask
}
```
But this doesn't work yet due to a missing support for AArch64ISD::MOVIshift in AArch64TargetLowering::computeKnownBitsForTargetNode

https://github.com/llvm/llvm-project/pull/148191


More information about the llvm-commits mailing list