llvm/llvm/test/CodeGen/AArch64/avg.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple=aarch64 < %s | FileCheck %s

define <16 x i16> @zext_avgflooru(<16 x i8> %a0, <16 x i8> %a1) {
; CHECK-LABEL: zext_avgflooru:
; CHECK:       // %bb.0:
; CHECK-NEXT:    uhadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    ushll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = zext <16 x i8> %a0 to <16 x i16>
  %x1 = zext <16 x i8> %a1 to <16 x i16>
  %and = and <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = add <16 x i16> %and, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @zext_avgflooru_mismatch(<16 x i8> %a0, <16 x i4> %a1) {
; CHECK-LABEL: zext_avgflooru_mismatch:
; CHECK:       // %bb.0:
; CHECK-NEXT:    movi v2.16b, #15
; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
; CHECK-NEXT:    uhadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    ushll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = zext <16 x i8> %a0 to <16 x i16>
  %x1 = zext <16 x i4> %a1 to <16 x i16>
  %and = and <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = add <16 x i16> %and, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @zext_avgceilu(<16 x i8> %a0, <16 x i8> %a1) {
; CHECK-LABEL: zext_avgceilu:
; CHECK:       // %bb.0:
; CHECK-NEXT:    urhadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    ushll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = zext <16 x i8> %a0 to <16 x i16>
  %x1 = zext <16 x i8> %a1 to <16 x i16>
  %or = or <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = sub <16 x i16> %or, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @zext_avgceilu_mismatch(<16 x i4> %a0, <16 x i8> %a1) {
; CHECK-LABEL: zext_avgceilu_mismatch:
; CHECK:       // %bb.0:
; CHECK-NEXT:    movi v2.16b, #15
; CHECK-NEXT:    and v0.16b, v0.16b, v2.16b
; CHECK-NEXT:    urhadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    ushll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = zext <16 x i4> %a0 to <16 x i16>
  %x1 = zext <16 x i8> %a1 to <16 x i16>
  %or = or <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = lshr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = sub <16 x i16> %or, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @sext_avgfloors(<16 x i8> %a0, <16 x i8> %a1) {
; CHECK-LABEL: sext_avgfloors:
; CHECK:       // %bb.0:
; CHECK-NEXT:    shadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    sshll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    sshll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = sext <16 x i8> %a0 to <16 x i16>
  %x1 = sext <16 x i8> %a1 to <16 x i16>
  %and = and <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = add <16 x i16> %and, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @sext_avgfloors_mismatch(<16 x i8> %a0, <16 x i4> %a1) {
; CHECK-LABEL: sext_avgfloors_mismatch:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ushll2 v2.8h, v1.16b, #0
; CHECK-NEXT:    ushll v1.8h, v1.8b, #0
; CHECK-NEXT:    sshll v3.8h, v0.8b, #0
; CHECK-NEXT:    sshll2 v0.8h, v0.16b, #0
; CHECK-NEXT:    shl v1.8h, v1.8h, #12
; CHECK-NEXT:    shl v2.8h, v2.8h, #12
; CHECK-NEXT:    sshr v4.8h, v1.8h, #12
; CHECK-NEXT:    sshr v1.8h, v2.8h, #12
; CHECK-NEXT:    shadd v1.8h, v0.8h, v1.8h
; CHECK-NEXT:    shadd v0.8h, v3.8h, v4.8h
; CHECK-NEXT:    ret
  %x0 = sext <16 x i8> %a0 to <16 x i16>
  %x1 = sext <16 x i4> %a1 to <16 x i16>
  %and = and <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = add <16 x i16> %and, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @sext_avgceils(<16 x i8> %a0, <16 x i8> %a1) {
; CHECK-LABEL: sext_avgceils:
; CHECK:       // %bb.0:
; CHECK-NEXT:    srhadd v0.16b, v0.16b, v1.16b
; CHECK-NEXT:    sshll2 v1.8h, v0.16b, #0
; CHECK-NEXT:    sshll v0.8h, v0.8b, #0
; CHECK-NEXT:    ret
  %x0 = sext <16 x i8> %a0 to <16 x i16>
  %x1 = sext <16 x i8> %a1 to <16 x i16>
  %or = or <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = sub <16 x i16> %or, %shift
  ret <16 x i16> %avg
}

define <16 x i16> @sext_avgceils_mismatch(<16 x i4> %a0, <16 x i8> %a1) {
; CHECK-LABEL: sext_avgceils_mismatch:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ushll v2.8h, v0.8b, #0
; CHECK-NEXT:    ushll2 v0.8h, v0.16b, #0
; CHECK-NEXT:    sshll v3.8h, v1.8b, #0
; CHECK-NEXT:    sshll2 v1.8h, v1.16b, #0
; CHECK-NEXT:    shl v2.8h, v2.8h, #12
; CHECK-NEXT:    shl v0.8h, v0.8h, #12
; CHECK-NEXT:    sshr v2.8h, v2.8h, #12
; CHECK-NEXT:    sshr v0.8h, v0.8h, #12
; CHECK-NEXT:    srhadd v1.8h, v0.8h, v1.8h
; CHECK-NEXT:    srhadd v0.8h, v2.8h, v3.8h
; CHECK-NEXT:    ret
  %x0 = sext <16 x i4> %a0 to <16 x i16>
  %x1 = sext <16 x i8> %a1 to <16 x i16>
  %or = or <16 x i16> %x0, %x1
  %xor = xor <16 x i16> %x0, %x1
  %shift = ashr <16 x i16> %xor, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
  %avg = sub <16 x i16> %or, %shift
  ret <16 x i16> %avg
}