llvm-project/clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

403 lines
14 KiB
C
Raw Normal View History

[ARM,MVE] Support immediate vbicq,vorrq,vmvnq intrinsics. Summary: Immediate vmvnq is code-generated as a simple vector constant in IR, and left to the backend to recognize that it can be created with an MVE VMVN instruction. The predicated version is represented as a select between the input and the same constant, and I've added a Tablegen isel rule to turn that into a predicated VMVN. (That should be better than the previous VMVN + VPSEL: it's the same number of instructions but now it can fold into an adjacent VPT block.) The unpredicated forms of VBIC and VORR are done by enabling the same isel lowering as for NEON, recognizing appropriate immediates and rewriting them as ARMISD::VBICIMM / ARMISD::VORRIMM SDNodes, which I then instruction-select into the right MVE instructions (now that I've also reworked those instructions to use the same MC operand encoding). In order to do that, I had to promote the Tablegen SDNode instance `NEONvorrImm` to a general `ARMvorrImm` available in MVE as well, and similarly for `NEONvbicImm`. The predicated forms of VBIC and VORR are represented as a vector select between the original input vector and the output of the unpredicated operation. The main convenience of this is that it still lets me use the existing isel lowering for VBICIMM/VORRIMM, and not have to write another copy of the operand encoding translation code. This intrinsic family is the first to use the `imm_simd` system I put into the MveEmitter tablegen backend. So, naturally, it showed up a bug or two (emitting bogus range checks and the like). Fixed those, and added a full set of tests for the permissible immediates in the existing Sema test. Also adjusted the isel pattern for `vmovlb.u8`, which stopped matching because lowering started turning its input into a VBICIMM. Now it recognizes the VBICIMM instead. Reviewers: dmgreen, MarkMurrayARM, miyuki, ostannard Reviewed By: dmgreen Subscribers: kristof.beyls, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D72934
2020-01-23 19:53:42 +08:00
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
[ARM,MVE] Support immediate vbicq,vorrq,vmvnq intrinsics. Summary: Immediate vmvnq is code-generated as a simple vector constant in IR, and left to the backend to recognize that it can be created with an MVE VMVN instruction. The predicated version is represented as a select between the input and the same constant, and I've added a Tablegen isel rule to turn that into a predicated VMVN. (That should be better than the previous VMVN + VPSEL: it's the same number of instructions but now it can fold into an adjacent VPT block.) The unpredicated forms of VBIC and VORR are done by enabling the same isel lowering as for NEON, recognizing appropriate immediates and rewriting them as ARMISD::VBICIMM / ARMISD::VORRIMM SDNodes, which I then instruction-select into the right MVE instructions (now that I've also reworked those instructions to use the same MC operand encoding). In order to do that, I had to promote the Tablegen SDNode instance `NEONvorrImm` to a general `ARMvorrImm` available in MVE as well, and similarly for `NEONvbicImm`. The predicated forms of VBIC and VORR are represented as a vector select between the original input vector and the output of the unpredicated operation. The main convenience of this is that it still lets me use the existing isel lowering for VBICIMM/VORRIMM, and not have to write another copy of the operand encoding translation code. This intrinsic family is the first to use the `imm_simd` system I put into the MveEmitter tablegen backend. So, naturally, it showed up a bug or two (emitting bogus range checks and the like). Fixed those, and added a full set of tests for the permissible immediates in the existing Sema test. Also adjusted the isel pattern for `vmovlb.u8`, which stopped matching because lowering started turning its input into a VBICIMM. Now it recognizes the VBICIMM instead. Reviewers: dmgreen, MarkMurrayARM, miyuki, ostannard Reviewed By: dmgreen Subscribers: kristof.beyls, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D72934
2020-01-23 19:53:42 +08:00
#include <arm_mve.h>
// CHECK-LABEL: @test_vbicq_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = and <8 x i16> [[A:%.*]], <i16 11007, i16 11007, i16 11007, i16 11007, i16 11007, i16 11007, i16 11007, i16 11007>
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
//
int16x8_t test_vbicq_n_s16(int16x8_t a)
{
#ifdef POLYMORPHIC
return vbicq(a, 0xd500);
#else /* POLYMORPHIC */
return vbicq_n_s16(a, 0xd500);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = and <4 x i32> [[A:%.*]], <i32 -252, i32 -252, i32 -252, i32 -252>
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
//
int32x4_t test_vbicq_n_s32(int32x4_t a)
{
#ifdef POLYMORPHIC
return vbicq(a, 0xfb);
#else /* POLYMORPHIC */
return vbicq_n_s32(a, 0xfb);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = and <8 x i16> [[A:%.*]], <i16 -243, i16 -243, i16 -243, i16 -243, i16 -243, i16 -243, i16 -243, i16 -243>
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
//
uint16x8_t test_vbicq_n_u16(uint16x8_t a)
{
#ifdef POLYMORPHIC
return vbicq(a, 0xf2);
#else /* POLYMORPHIC */
return vbicq_n_u16(a, 0xf2);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = and <4 x i32> [[A:%.*]], <i32 -8193, i32 -8193, i32 -8193, i32 -8193>
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
//
uint32x4_t test_vbicq_n_u32(uint32x4_t a)
{
#ifdef POLYMORPHIC
return vbicq(a, 0x2000);
#else /* POLYMORPHIC */
return vbicq_n_u32(a, 0x2000);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = or <8 x i16> [[A:%.*]], <i16 195, i16 195, i16 195, i16 195, i16 195, i16 195, i16 195, i16 195>
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
//
int16x8_t test_vorrq_n_s16(int16x8_t a)
{
#ifdef POLYMORPHIC
return vorrq(a, 0xc3);
#else /* POLYMORPHIC */
return vorrq_n_s16(a, 0xc3);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = or <4 x i32> [[A:%.*]], <i32 65536, i32 65536, i32 65536, i32 65536>
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
//
int32x4_t test_vorrq_n_s32(int32x4_t a)
{
#ifdef POLYMORPHIC
return vorrq(a, 0x10000);
#else /* POLYMORPHIC */
return vorrq_n_s32(a, 0x10000);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = or <8 x i16> [[A:%.*]], <i16 -4096, i16 -4096, i16 -4096, i16 -4096, i16 -4096, i16 -4096, i16 -4096, i16 -4096>
// CHECK-NEXT: ret <8 x i16> [[TMP0]]
//
uint16x8_t test_vorrq_n_u16(uint16x8_t a)
{
#ifdef POLYMORPHIC
return vorrq(a, 0xf000);
#else /* POLYMORPHIC */
return vorrq_n_u16(a, 0xf000);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = or <4 x i32> [[A:%.*]], <i32 8978432, i32 8978432, i32 8978432, i32 8978432>
// CHECK-NEXT: ret <4 x i32> [[TMP0]]
//
uint32x4_t test_vorrq_n_u32(uint32x4_t a)
{
#ifdef POLYMORPHIC
return vorrq(a, 0x890000);
#else /* POLYMORPHIC */
return vorrq_n_u32(a, 0x890000);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x i16> <i16 27391, i16 27391, i16 27391, i16 27391, i16 27391, i16 27391, i16 27391, i16 27391>
//
int16x8_t test_vmvnq_n_s16()
{
return vmvnq_n_s16(0x9500);
}
// CHECK-LABEL: @test_vmvnq_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <4 x i32> <i32 -5570561, i32 -5570561, i32 -5570561, i32 -5570561>
//
int32x4_t test_vmvnq_n_s32()
{
return vmvnq_n_s32(0x550000);
}
// CHECK-LABEL: @test_vmvnq_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x i16> <i16 -18689, i16 -18689, i16 -18689, i16 -18689, i16 -18689, i16 -18689, i16 -18689, i16 -18689>
//
uint16x8_t test_vmvnq_n_u16()
{
return vmvnq_n_u16(0x4900);
}
// CHECK-LABEL: @test_vmvnq_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <4 x i32> <i32 1023410175, i32 1023410175, i32 1023410175, i32 1023410175>
//
uint32x4_t test_vmvnq_n_u32()
{
return vmvnq_n_u32(0xc3000000);
}
// CHECK-LABEL: @test_vbicq_m_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = and <8 x i16> [[A:%.*]], <i16 -11265, i16 -11265, i16 -11265, i16 -11265, i16 -11265, i16 -11265, i16 -11265, i16 -11265>
// CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[TMP2]], <8 x i16> [[A]]
// CHECK-NEXT: ret <8 x i16> [[TMP3]]
//
int16x8_t test_vbicq_m_n_s16(int16x8_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vbicq_m_n(a, 0x2c00, p);
#else /* POLYMORPHIC */
return vbicq_m_n_s16(a, 0x2c00, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_m_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[A:%.*]], <i32 -13893633, i32 -13893633, i32 -13893633, i32 -13893633>
// CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP2]], <4 x i32> [[A]]
// CHECK-NEXT: ret <4 x i32> [[TMP3]]
//
int32x4_t test_vbicq_m_n_s32(int32x4_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vbicq_m_n(a, 0xd40000, p);
#else /* POLYMORPHIC */
return vbicq_m_n_s32(a, 0xd40000, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_m_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = and <8 x i16> [[A:%.*]], <i16 -37, i16 -37, i16 -37, i16 -37, i16 -37, i16 -37, i16 -37, i16 -37>
// CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[TMP2]], <8 x i16> [[A]]
// CHECK-NEXT: ret <8 x i16> [[TMP3]]
//
uint16x8_t test_vbicq_m_n_u16(uint16x8_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vbicq_m_n(a, 0x24, p);
#else /* POLYMORPHIC */
return vbicq_m_n_u16(a, 0x24, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vbicq_m_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1644167169, i32 -1644167169, i32 -1644167169, i32 -1644167169>
// CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP2]], <4 x i32> [[A]]
// CHECK-NEXT: ret <4 x i32> [[TMP3]]
//
uint32x4_t test_vbicq_m_n_u32(uint32x4_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vbicq_m_n(a, 0x62000000, p);
#else /* POLYMORPHIC */
return vbicq_m_n_u32(a, 0x62000000, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_m_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = or <8 x i16> [[A:%.*]], <i16 13568, i16 13568, i16 13568, i16 13568, i16 13568, i16 13568, i16 13568, i16 13568>
// CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[TMP2]], <8 x i16> [[A]]
// CHECK-NEXT: ret <8 x i16> [[TMP3]]
//
int16x8_t test_vorrq_m_n_s16(int16x8_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vorrq_m_n(a, 0x3500, p);
#else /* POLYMORPHIC */
return vorrq_m_n_s16(a, 0x3500, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_m_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = or <4 x i32> [[A:%.*]], <i32 654311424, i32 654311424, i32 654311424, i32 654311424>
// CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP2]], <4 x i32> [[A]]
// CHECK-NEXT: ret <4 x i32> [[TMP3]]
//
int32x4_t test_vorrq_m_n_s32(int32x4_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vorrq_m_n(a, 0x27000000, p);
#else /* POLYMORPHIC */
return vorrq_m_n_s32(a, 0x27000000, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_m_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = or <8 x i16> [[A:%.*]], <i16 175, i16 175, i16 175, i16 175, i16 175, i16 175, i16 175, i16 175>
// CHECK-NEXT: [[TMP3:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[TMP2]], <8 x i16> [[A]]
// CHECK-NEXT: ret <8 x i16> [[TMP3]]
//
uint16x8_t test_vorrq_m_n_u16(uint16x8_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vorrq_m_n(a, 0xaf, p);
#else /* POLYMORPHIC */
return vorrq_m_n_u16(a, 0xaf, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vorrq_m_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = or <4 x i32> [[A:%.*]], <i32 89, i32 89, i32 89, i32 89>
// CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP2]], <4 x i32> [[A]]
// CHECK-NEXT: ret <4 x i32> [[TMP3]]
//
uint32x4_t test_vorrq_m_n_u32(uint32x4_t a, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vorrq_m_n(a, 0x59, p);
#else /* POLYMORPHIC */
return vorrq_m_n_u32(a, 0x59, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_m_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> <i16 -3841, i16 -3841, i16 -3841, i16 -3841, i16 -3841, i16 -3841, i16 -3841, i16 -3841>, <8 x i16> [[INACTIVE:%.*]]
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
//
int16x8_t test_vmvnq_m_n_s16(int16x8_t inactive, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vmvnq_m(inactive, 0xf00, p);
#else /* POLYMORPHIC */
return vmvnq_m_n_s16(inactive, 0xf00, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_m_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -18945, i32 -18945, i32 -18945, i32 -18945>, <4 x i32> [[INACTIVE:%.*]]
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
//
int32x4_t test_vmvnq_m_n_s32(int32x4_t inactive, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vmvnq_m(inactive, 0x4a00, p);
#else /* POLYMORPHIC */
return vmvnq_m_n_s32(inactive, 0x4a00, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_m_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> <i16 23295, i16 23295, i16 23295, i16 23295, i16 23295, i16 23295, i16 23295, i16 23295>, <8 x i16> [[INACTIVE:%.*]]
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
//
uint16x8_t test_vmvnq_m_n_u16(uint16x8_t inactive, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vmvnq_m(inactive, 0xa500, p);
#else /* POLYMORPHIC */
return vmvnq_m_n_u16(inactive, 0xa500, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_m_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -63489, i32 -63489, i32 -63489, i32 -63489>, <4 x i32> [[INACTIVE:%.*]]
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
//
uint32x4_t test_vmvnq_m_n_u32(uint32x4_t inactive, mve_pred16_t p)
{
#ifdef POLYMORPHIC
return vmvnq_m(inactive, 0xf800, p);
#else /* POLYMORPHIC */
return vmvnq_m_n_u32(inactive, 0xf800, p);
#endif /* POLYMORPHIC */
}
// CHECK-LABEL: @test_vmvnq_x_n_s16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> <i16 767, i16 767, i16 767, i16 767, i16 767, i16 767, i16 767, i16 767>, <8 x i16> undef
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
//
int16x8_t test_vmvnq_x_n_s16(mve_pred16_t p)
{
return vmvnq_x_n_s16(0xfd00, p);
}
// CHECK-LABEL: @test_vmvnq_x_n_s32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -12189697, i32 -12189697, i32 -12189697, i32 -12189697>, <4 x i32> undef
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
//
int32x4_t test_vmvnq_x_n_s32(mve_pred16_t p)
{
return vmvnq_x_n_s32(0xba0000, p);
}
// CHECK-LABEL: @test_vmvnq_x_n_u16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> <i16 -21505, i16 -21505, i16 -21505, i16 -21505, i16 -21505, i16 -21505, i16 -21505, i16 -21505>, <8 x i16> undef
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
//
uint16x8_t test_vmvnq_x_n_u16(mve_pred16_t p)
{
return vmvnq_x_n_u16(0x5400, p);
}
// CHECK-LABEL: @test_vmvnq_x_n_u32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -4865, i32 -4865, i32 -4865, i32 -4865>, <4 x i32> undef
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
//
uint32x4_t test_vmvnq_x_n_u32(mve_pred16_t p)
{
return vmvnq_x_n_u32(0x1300, p);
}