; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve.fp -verify-machineinstrs -o - %s | FileCheck %s

define arm_aapcs_vfpcc signext i8 @test_vminvq_s8(i8 signext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vminvq_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.s8 r0, q0
; CHECK-NEXT:    sxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minv.v16i8(i32 %0, <16 x i8> %b, i32 0)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc signext i16 @test_vminvq_s16(i16 signext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vminvq_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.s16 r0, q0
; CHECK-NEXT:    sxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minv.v8i16(i32 %0, <8 x i16> %b, i32 0)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vminvq_s32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vminvq_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.minv.v4i32(i32 %a, <4 x i32> %b, i32 0)
  ret i32 %0
}

define arm_aapcs_vfpcc zeroext i8 @test_vminvq_u8(i8 zeroext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vminvq_u8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.u8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minv.v16i8(i32 %0, <16 x i8> %b, i32 1)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc zeroext i16 @test_vminvq_u16(i16 zeroext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vminvq_u16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.u16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minv.v8i16(i32 %0, <8 x i16> %b, i32 1)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vminvq_u32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vminvq_u32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminv.u32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.minv.v4i32(i32 %a, <4 x i32> %b, i32 1)
  ret i32 %0
}

define arm_aapcs_vfpcc signext i8 @test_vmaxvq_s8(i8 signext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vmaxvq_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.s8 r0, q0
; CHECK-NEXT:    sxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxv.v16i8(i32 %0, <16 x i8> %b, i32 0)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc signext i16 @test_vmaxvq_s16(i16 signext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vmaxvq_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.s16 r0, q0
; CHECK-NEXT:    sxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxv.v8i16(i32 %0, <8 x i16> %b, i32 0)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vmaxvq_s32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vmaxvq_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.maxv.v4i32(i32 %a, <4 x i32> %b, i32 0)
  ret i32 %0
}

define arm_aapcs_vfpcc zeroext i8 @test_vmaxvq_u8(i8 zeroext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vmaxvq_u8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.u8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxv.v16i8(i32 %0, <16 x i8> %b, i32 1)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc zeroext i16 @test_vmaxvq_u16(i16 zeroext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vmaxvq_u16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.u16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxv.v8i16(i32 %0, <8 x i16> %b, i32 1)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vmaxvq_u32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vmaxvq_u32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxv.u32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.maxv.v4i32(i32 %a, <4 x i32> %b, i32 1)
  ret i32 %0
}

define arm_aapcs_vfpcc zeroext i8 @test_vminavq_s8(i8 zeroext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vminavq_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminav.s8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minav.v16i8(i32 %0, <16 x i8> %b)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc zeroext i16 @test_vminavq_s16(i16 zeroext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vminavq_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminav.s16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.minav.v8i16(i32 %0, <8 x i16> %b)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vminavq_s32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vminavq_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vminav.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.minav.v4i32(i32 %a, <4 x i32> %b)
  ret i32 %0
}

define arm_aapcs_vfpcc zeroext i8 @test_vmaxavq_s8(i8 zeroext %a, <16 x i8> %b) {
; CHECK-LABEL: test_vmaxavq_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxav.s8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxav.v16i8(i32 %0, <16 x i8> %b)
  %2 = trunc i32 %1 to i8
  ret i8 %2
}

define arm_aapcs_vfpcc zeroext i16 @test_vmaxavq_s16(i16 zeroext %a, <8 x i16> %b) {
; CHECK-LABEL: test_vmaxavq_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxav.s16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = tail call i32 @llvm.arm.mve.maxav.v8i16(i32 %0, <8 x i16> %b)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

define arm_aapcs_vfpcc i32 @test_vmaxavq_s32(i32 %a, <4 x i32> %b) {
; CHECK-LABEL: test_vmaxavq_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmaxav.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call i32 @llvm.arm.mve.maxav.v4i32(i32 %a, <4 x i32> %b)
  ret i32 %0
}

define arm_aapcs_vfpcc float @test_vminnmvq_f16(float %a.coerce, <8 x half> %b) {
; CHECK-LABEL: test_vminnmvq_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vminnmv.f16 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = tail call half @llvm.arm.mve.minnmv.f16.v8f16(half %1, <8 x half> %b)
  %3 = bitcast half %2 to i16
  %tmp2.0.insert.ext = zext i16 %3 to i32
  %4 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %4
}

define arm_aapcs_vfpcc float @test_vminnmvq_f32(float %a, <4 x float> %b) {
; CHECK-LABEL: test_vminnmvq_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vminnmv.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call float @llvm.arm.mve.minnmv.f32.v4f32(float %a, <4 x float> %b)
  ret float %0
}

define arm_aapcs_vfpcc float @test_vminnmavq_f16(float %a.coerce, <8 x half> %b) {
; CHECK-LABEL: test_vminnmavq_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vminnmav.f16 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = tail call half @llvm.arm.mve.minnmav.f16.v8f16(half %1, <8 x half> %b)
  %3 = bitcast half %2 to i16
  %tmp2.0.insert.ext = zext i16 %3 to i32
  %4 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %4
}

define arm_aapcs_vfpcc float @test_vminnmavq_f32(float %a, <4 x float> %b) {
; CHECK-LABEL: test_vminnmavq_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vminnmav.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call float @llvm.arm.mve.minnmav.f32.v4f32(float %a, <4 x float> %b)
  ret float %0
}

define arm_aapcs_vfpcc float @test_vmaxnmvq_f16(float %a.coerce, <8 x half> %b) {
; CHECK-LABEL: test_vmaxnmvq_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vmaxnmv.f16 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = tail call half @llvm.arm.mve.maxnmv.f16.v8f16(half %1, <8 x half> %b)
  %3 = bitcast half %2 to i16
  %tmp2.0.insert.ext = zext i16 %3 to i32
  %4 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %4
}

define arm_aapcs_vfpcc float @test_vmaxnmvq_f32(float %a, <4 x float> %b) {
; CHECK-LABEL: test_vmaxnmvq_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vmaxnmv.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call float @llvm.arm.mve.maxnmv.f32.v4f32(float %a, <4 x float> %b)
  ret float %0
}

define arm_aapcs_vfpcc float @test_vmaxnmavq_f16(float %a.coerce, <8 x half> %b) {
; CHECK-LABEL: test_vmaxnmavq_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vmaxnmav.f16 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = tail call half @llvm.arm.mve.maxnmav.f16.v8f16(half %1, <8 x half> %b)
  %3 = bitcast half %2 to i16
  %tmp2.0.insert.ext = zext i16 %3 to i32
  %4 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %4
}

define arm_aapcs_vfpcc float @test_vmaxnmavq_f32(float %a, <4 x float> %b) {
; CHECK-LABEL: test_vmaxnmavq_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vmaxnmav.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = tail call float @llvm.arm.mve.maxnmav.f32.v4f32(float %a, <4 x float> %b)
  ret float %0
}

define arm_aapcs_vfpcc signext i8 @test_vminvq_p_s8(i8 signext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.s8 r0, q0
; CHECK-NEXT:    sxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minv.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, i32 0, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc signext i16 @test_vminvq_p_s16(i16 signext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.s16 r0, q0
; CHECK-NEXT:    sxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minv.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, i32 0, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vminvq_p_s32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.minv.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, i32 0, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc zeroext i8 @test_vminvq_p_u8(i8 zeroext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_u8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.u8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minv.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, i32 1, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc zeroext i16 @test_vminvq_p_u16(i16 zeroext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_u16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.u16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minv.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, i32 1, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vminvq_p_u32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminvq_p_u32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminvt.u32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.minv.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, i32 1, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc signext i8 @test_vmaxvq_p_s8(i8 signext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.s8 r0, q0
; CHECK-NEXT:    sxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxv.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, i32 0, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc signext i16 @test_vmaxvq_p_s16(i16 signext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.s16 r0, q0
; CHECK-NEXT:    sxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxv.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, i32 0, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vmaxvq_p_s32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.maxv.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, i32 0, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc zeroext i8 @test_vmaxvq_p_u8(i8 zeroext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_u8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.u8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxv.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, i32 1, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc zeroext i16 @test_vmaxvq_p_u16(i16 zeroext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_u16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.u16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxv.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, i32 1, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vmaxvq_p_u32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxvq_p_u32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxvt.u32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.maxv.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, i32 1, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc zeroext i8 @test_vminavq_p_s8(i8 zeroext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminavq_p_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminavt.s8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minav.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc zeroext i16 @test_vminavq_p_s16(i16 zeroext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminavq_p_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminavt.s16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.minav.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vminavq_p_s32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminavq_p_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminavt.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.minav.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc zeroext i8 @test_vmaxavq_p_s8(i8 zeroext %a, <16 x i8> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxavq_p_s8:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxavt.s8 r0, q0
; CHECK-NEXT:    uxtb r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i8 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxav.predicated.v16i8.v16i1(i32 %0, <16 x i8> %b, <16 x i1> %2)
  %4 = trunc i32 %3 to i8
  ret i8 %4
}

define arm_aapcs_vfpcc zeroext i16 @test_vmaxavq_p_s16(i16 zeroext %a, <8 x i16> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxavq_p_s16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxavt.s16 r0, q0
; CHECK-NEXT:    uxth r0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %a to i32
  %1 = zext i16 %p to i32
  %2 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %1)
  %3 = tail call i32 @llvm.arm.mve.maxav.predicated.v8i16.v8i1(i32 %0, <8 x i16> %b, <8 x i1> %2)
  %4 = trunc i32 %3 to i16
  ret i16 %4
}

define arm_aapcs_vfpcc i32 @test_vmaxavq_p_s32(i32 %a, <4 x i32> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxavq_p_s32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r1
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxavt.s32 r0, q0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call i32 @llvm.arm.mve.maxav.predicated.v4i32.v4i1(i32 %a, <4 x i32> %b, <4 x i1> %1)
  ret i32 %2
}

define arm_aapcs_vfpcc float @test_vminnmvq_p_f16(float %a.coerce, <8 x half> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminnmvq_p_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r1, s0
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminnmvt.f16 r1, q1
; CHECK-NEXT:    vmov s0, r1
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = zext i16 %p to i32
  %3 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %2)
  %4 = tail call half @llvm.arm.mve.minnmv.predicated.f16.v8f16.v8i1(half %1, <8 x half> %b, <8 x i1> %3)
  %5 = bitcast half %4 to i16
  %tmp2.0.insert.ext = zext i16 %5 to i32
  %6 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %6
}

define arm_aapcs_vfpcc float @test_vminnmvq_p_f32(float %a, <4 x float> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminnmvq_p_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminnmvt.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call float @llvm.arm.mve.minnmv.predicated.f32.v4f32.v4i1(float %a, <4 x float> %b, <4 x i1> %1)
  ret float %2
}

define arm_aapcs_vfpcc float @test_vminnmavq_p_f16(float %a.coerce, <8 x half> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminnmavq_p_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r1, s0
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminnmavt.f16 r1, q1
; CHECK-NEXT:    vmov s0, r1
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = zext i16 %p to i32
  %3 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %2)
  %4 = tail call half @llvm.arm.mve.minnmav.predicated.f16.v8f16.v8i1(half %1, <8 x half> %b, <8 x i1> %3)
  %5 = bitcast half %4 to i16
  %tmp2.0.insert.ext = zext i16 %5 to i32
  %6 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %6
}

define arm_aapcs_vfpcc float @test_vminnmavq_p_f32(float %a, <4 x float> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vminnmavq_p_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vminnmavt.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call float @llvm.arm.mve.minnmav.predicated.f32.v4f32.v4i1(float %a, <4 x float> %b, <4 x i1> %1)
  ret float %2
}

define arm_aapcs_vfpcc float @test_vmaxnmvq_p_f16(float %a.coerce, <8 x half> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxnmvq_p_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r1, s0
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxnmvt.f16 r1, q1
; CHECK-NEXT:    vmov s0, r1
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = zext i16 %p to i32
  %3 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %2)
  %4 = tail call half @llvm.arm.mve.maxnmv.predicated.f16.v8f16.v8i1(half %1, <8 x half> %b, <8 x i1> %3)
  %5 = bitcast half %4 to i16
  %tmp2.0.insert.ext = zext i16 %5 to i32
  %6 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %6
}

define arm_aapcs_vfpcc float @test_vmaxnmvq_p_f32(float %a, <4 x float> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxnmvq_p_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxnmvt.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call float @llvm.arm.mve.maxnmv.predicated.f32.v4f32.v4i1(float %a, <4 x float> %b, <4 x i1> %1)
  ret float %2
}

define arm_aapcs_vfpcc float @test_vmaxnmavq_p_f16(float %a.coerce, <8 x half> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxnmavq_p_f16:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmov r1, s0
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxnmavt.f16 r1, q1
; CHECK-NEXT:    vmov s0, r1
; CHECK-NEXT:    vmov.f16 r0, s0
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = bitcast float %a.coerce to i32
  %tmp.0.extract.trunc = trunc i32 %0 to i16
  %1 = bitcast i16 %tmp.0.extract.trunc to half
  %2 = zext i16 %p to i32
  %3 = tail call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 %2)
  %4 = tail call half @llvm.arm.mve.maxnmav.predicated.f16.v8f16.v8i1(half %1, <8 x half> %b, <8 x i1> %3)
  %5 = bitcast half %4 to i16
  %tmp2.0.insert.ext = zext i16 %5 to i32
  %6 = bitcast i32 %tmp2.0.insert.ext to float
  ret float %6
}

define arm_aapcs_vfpcc float @test_vmaxnmavq_p_f32(float %a, <4 x float> %b, i16 zeroext %p) {
; CHECK-LABEL: test_vmaxnmavq_p_f32:
; CHECK:       @ %bb.0: @ %entry
; CHECK-NEXT:    vmsr p0, r0
; CHECK-NEXT:    vmov r0, s0
; CHECK-NEXT:    vpst
; CHECK-NEXT:    vmaxnmavt.f32 r0, q1
; CHECK-NEXT:    vmov s0, r0
; CHECK-NEXT:    bx lr
entry:
  %0 = zext i16 %p to i32
  %1 = tail call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 %0)
  %2 = tail call float @llvm.arm.mve.maxnmav.predicated.f32.v4f32.v4i1(float %a, <4 x float> %b, <4 x i1> %1)
  ret float %2
}

declare <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32)
declare <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32)
declare <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32)

declare i32 @llvm.arm.mve.minv.v16i8(i32, <16 x i8>, i32)
declare i32 @llvm.arm.mve.minv.v8i16(i32, <8 x i16>, i32)
declare i32 @llvm.arm.mve.minv.v4i32(i32, <4 x i32>, i32)
declare i32 @llvm.arm.mve.maxv.v16i8(i32, <16 x i8>, i32)
declare i32 @llvm.arm.mve.maxv.v8i16(i32, <8 x i16>, i32)
declare i32 @llvm.arm.mve.maxv.v4i32(i32, <4 x i32>, i32)
declare i32 @llvm.arm.mve.minav.v16i8(i32, <16 x i8>)
declare i32 @llvm.arm.mve.minav.v8i16(i32, <8 x i16>)
declare i32 @llvm.arm.mve.minav.v4i32(i32, <4 x i32>)
declare i32 @llvm.arm.mve.maxav.v16i8(i32, <16 x i8>)
declare i32 @llvm.arm.mve.maxav.v8i16(i32, <8 x i16>)
declare i32 @llvm.arm.mve.maxav.v4i32(i32, <4 x i32>)
declare i32 @llvm.arm.mve.minv.predicated.v16i8.v16i1(i32, <16 x i8>, i32, <16 x i1>)
declare i32 @llvm.arm.mve.minv.predicated.v8i16.v8i1(i32, <8 x i16>, i32, <8 x i1>)
declare i32 @llvm.arm.mve.minv.predicated.v4i32.v4i1(i32, <4 x i32>, i32, <4 x i1>)
declare i32 @llvm.arm.mve.maxv.predicated.v16i8.v16i1(i32, <16 x i8>, i32, <16 x i1>)
declare i32 @llvm.arm.mve.maxv.predicated.v8i16.v8i1(i32, <8 x i16>, i32, <8 x i1>)
declare i32 @llvm.arm.mve.maxv.predicated.v4i32.v4i1(i32, <4 x i32>, i32, <4 x i1>)
declare i32 @llvm.arm.mve.minav.predicated.v16i8.v16i1(i32, <16 x i8>, <16 x i1>)
declare i32 @llvm.arm.mve.minav.predicated.v8i16.v8i1(i32, <8 x i16>, <8 x i1>)
declare i32 @llvm.arm.mve.minav.predicated.v4i32.v4i1(i32, <4 x i32>, <4 x i1>)
declare i32 @llvm.arm.mve.maxav.predicated.v16i8.v16i1(i32, <16 x i8>, <16 x i1>)
declare i32 @llvm.arm.mve.maxav.predicated.v8i16.v8i1(i32, <8 x i16>, <8 x i1>)
declare i32 @llvm.arm.mve.maxav.predicated.v4i32.v4i1(i32, <4 x i32>, <4 x i1>)

declare half @llvm.arm.mve.minnmv.f16.v8f16(half, <8 x half>)
declare half @llvm.arm.mve.minnmav.f16.v8f16(half, <8 x half>)
declare half @llvm.arm.mve.maxnmv.f16.v8f16(half, <8 x half>)
declare half @llvm.arm.mve.maxnmav.f16.v8f16(half, <8 x half>)
declare half @llvm.arm.mve.minnmv.predicated.f16.v8f16.v8i1(half, <8 x half>, <8 x i1>)
declare half @llvm.arm.mve.minnmav.predicated.f16.v8f16.v8i1(half, <8 x half>, <8 x i1>)
declare half @llvm.arm.mve.maxnmv.predicated.f16.v8f16.v8i1(half, <8 x half>, <8 x i1>)
declare half @llvm.arm.mve.maxnmav.predicated.f16.v8f16.v8i1(half, <8 x half>, <8 x i1>)

declare float @llvm.arm.mve.minnmv.f32.v4f32(float, <4 x float>)
declare float @llvm.arm.mve.minnmav.f32.v4f32(float, <4 x float>)
declare float @llvm.arm.mve.maxnmv.f32.v4f32(float, <4 x float>)
declare float @llvm.arm.mve.maxnmav.f32.v4f32(float, <4 x float>)
declare float @llvm.arm.mve.minnmv.predicated.f32.v4f32.v4i1(float, <4 x float>, <4 x i1>)
declare float @llvm.arm.mve.minnmav.predicated.f32.v4f32.v4i1(float, <4 x float>, <4 x i1>)
declare float @llvm.arm.mve.maxnmv.predicated.f32.v4f32.v4i1(float, <4 x float>, <4 x i1>)
declare float @llvm.arm.mve.maxnmav.predicated.f32.v4f32.v4i1(float, <4 x float>, <4 x i1>)
