https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/225968
>From 96796a33fe9c1f31faf7dc24f3420f7cc48eed03 Mon Sep 17 00:00:00 2001 From: Craig Topper <[email protected]> Date: Wed, 23 Sep 2026 15:17:51 -0700 Subject: [PATCH 1/2] [RISCV][P-Ext] Add builtins and IR intrinsics for packed shifts. The packed shift instructions use 5-bit shift amounts regardless of element width. The C intrinsic should match this which means we can't use C shift operators to implement them. --- clang/include/clang/Basic/BuiltinsRISCV.td | 19 + clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 37 ++ clang/lib/Headers/riscv_packed_simd.h | 59 ++- clang/test/CodeGen/RISCV/rvp-intrinsics.c | 392 ++++++-------------- llvm/include/llvm/IR/IntrinsicsRISCV.td | 5 + llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 +- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 30 +- llvm/test/CodeGen/RISCV/rvp-simd-32.ll | 62 +++- llvm/test/CodeGen/RISCV/rvp-simd-64.ll | 162 +++++++- 9 files changed, 436 insertions(+), 348 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index 9065e9e363a56..046692899b237 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -203,6 +203,25 @@ def paas_x_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int def pasa_x_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>)">; def pasa_x_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>)">; +// Packed Shifts (32-bit) +def psll_s_u8x4 : RISCVBuiltin<"_Vector<4, unsigned char>(_Vector<4, unsigned char>, unsigned int)">; +def psll_s_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned short>, unsigned int)">; +def psrl_s_u8x4 : RISCVBuiltin<"_Vector<4, unsigned char>(_Vector<4, unsigned char>, unsigned int)">; +def psrl_s_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned short>, unsigned int)">; +def psra_s_i8x4 : RISCVBuiltin<"_Vector<4, signed char>(_Vector<4, signed char>, unsigned int)">; +def psra_s_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, unsigned int)">; + +// Packed Shifts (64-bit) +def psll_s_u8x8 : RISCVBuiltin<"_Vector<8, unsigned char>(_Vector<8, unsigned char>, unsigned int)">; +def psll_s_u16x4 : RISCVBuiltin<"_Vector<4, unsigned short>(_Vector<4, unsigned short>, unsigned int)">; +def psll_s_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, unsigned int)">; +def psrl_s_u8x8 : RISCVBuiltin<"_Vector<8, unsigned char>(_Vector<8, unsigned char>, unsigned int)">; +def psrl_s_u16x4 : RISCVBuiltin<"_Vector<4, unsigned short>(_Vector<4, unsigned short>, unsigned int)">; +def psrl_s_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, unsigned int)">; +def psra_s_i8x8 : RISCVBuiltin<"_Vector<8, signed char>(_Vector<8, signed char>, unsigned int)">; +def psra_s_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, unsigned int)">; +def psra_s_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, unsigned int)">; + // Packed Absolute Value and Absolute Difference (32-bit) def pabd_i8x4 : RISCVBuiltin<"_Vector<4, unsigned char>(_Vector<4, signed char>, _Vector<4, signed char>)">; def pabd_i16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, short>, _Vector<2, short>)">; diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index 82c69f5d87dcf..b1892d6e09278 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1239,6 +1239,22 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pasa_x_i16x2: case RISCV::BI__builtin_riscv_pasa_x_i16x4: case RISCV::BI__builtin_riscv_pasa_x_i32x2: + // Packed Shift + case RISCV::BI__builtin_riscv_psll_s_u8x4: + case RISCV::BI__builtin_riscv_psll_s_u16x2: + case RISCV::BI__builtin_riscv_psll_s_u8x8: + case RISCV::BI__builtin_riscv_psll_s_u16x4: + case RISCV::BI__builtin_riscv_psll_s_u32x2: + case RISCV::BI__builtin_riscv_psrl_s_u8x4: + case RISCV::BI__builtin_riscv_psrl_s_u16x2: + case RISCV::BI__builtin_riscv_psrl_s_u8x8: + case RISCV::BI__builtin_riscv_psrl_s_u16x4: + case RISCV::BI__builtin_riscv_psrl_s_u32x2: + case RISCV::BI__builtin_riscv_psra_s_i8x4: + case RISCV::BI__builtin_riscv_psra_s_i16x2: + case RISCV::BI__builtin_riscv_psra_s_i8x8: + case RISCV::BI__builtin_riscv_psra_s_i16x4: + case RISCV::BI__builtin_riscv_psra_s_i32x2: // Packed Absolute Value and Absolute Difference case RISCV::BI__builtin_riscv_pabd_i8x4: case RISCV::BI__builtin_riscv_pabd_i16x2: @@ -1390,6 +1406,27 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pasa_x_i32x2: ID = Intrinsic::riscv_pasa; break; + case RISCV::BI__builtin_riscv_psll_s_u8x4: + case RISCV::BI__builtin_riscv_psll_s_u16x2: + case RISCV::BI__builtin_riscv_psll_s_u8x8: + case RISCV::BI__builtin_riscv_psll_s_u16x4: + case RISCV::BI__builtin_riscv_psll_s_u32x2: + ID = Intrinsic::riscv_psll; + break; + case RISCV::BI__builtin_riscv_psrl_s_u8x4: + case RISCV::BI__builtin_riscv_psrl_s_u16x2: + case RISCV::BI__builtin_riscv_psrl_s_u8x8: + case RISCV::BI__builtin_riscv_psrl_s_u16x4: + case RISCV::BI__builtin_riscv_psrl_s_u32x2: + ID = Intrinsic::riscv_psrl; + break; + case RISCV::BI__builtin_riscv_psra_s_i8x4: + case RISCV::BI__builtin_riscv_psra_s_i16x2: + case RISCV::BI__builtin_riscv_psra_s_i8x8: + case RISCV::BI__builtin_riscv_psra_s_i16x4: + case RISCV::BI__builtin_riscv_psra_s_i32x2: + ID = Intrinsic::riscv_psra; + break; case RISCV::BI__builtin_riscv_pabd_i8x4: case RISCV::BI__builtin_riscv_pabd_i16x2: case RISCV::BI__builtin_riscv_pabd_i8x8: diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index 2cee5987c1dac..53062e62f17a1 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -41,15 +41,6 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8))); return splat(ty, __x); \ } -#define __packed_shift(name, ty, op, mask) \ - static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \ - unsigned __rs2) { \ - return __rs1 op(__rs2 & (mask)); \ - } -#define __packed_shift8(name, ty, op) __packed_shift(name, ty, op, 0x7) -#define __packed_shift16(name, ty, op) __packed_shift(name, ty, op, 0xf) -#define __packed_shift32(name, ty, op) __packed_shift(name, ty, op, 0x1f) - #define __packed_scalar_binary_op(name, ty, scalar_ty, op, splat) \ static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, \ scalar_ty __rs2) { \ @@ -610,29 +601,29 @@ __packed_cmp(pmsgeu_u32x2, uint32x2_t, uint32x2_t, >=) __packed_cmp(pmsle_u32x2, int32x2_t, uint32x2_t, <=) __packed_cmp(pmsleu_u32x2, uint32x2_t, uint32x2_t, <=) -/* Packed Shifts (32-bit) */ -__packed_shift8(psll_s_u8x4, uint8x4_t, <<) -__packed_shift8(psll_s_i8x4, int8x4_t, <<) -__packed_shift16(psll_s_u16x2, uint16x2_t, <<) -__packed_shift16(psll_s_i16x2, int16x2_t, <<) -__packed_shift8(psrl_s_u8x4, uint8x4_t, >>) -__packed_shift16(psrl_s_u16x2, uint16x2_t, >>) -__packed_shift8(psra_s_i8x4, int8x4_t, >>) -__packed_shift16(psra_s_i16x2, int16x2_t, >>) - -/* Packed Shifts (64-bit) */ -__packed_shift8(psll_s_u8x8, uint8x8_t, <<) -__packed_shift8(psll_s_i8x8, int8x8_t, <<) -__packed_shift16(psll_s_u16x4, uint16x4_t, <<) -__packed_shift16(psll_s_i16x4, int16x4_t, <<) -__packed_shift32(psll_s_u32x2, uint32x2_t, <<) -__packed_shift32(psll_s_i32x2, int32x2_t, <<) -__packed_shift8(psrl_s_u8x8, uint8x8_t, >>) -__packed_shift16(psrl_s_u16x4, uint16x4_t, >>) -__packed_shift32(psrl_s_u32x2, uint32x2_t, >>) -__packed_shift8(psra_s_i8x8, int8x8_t, >>) -__packed_shift16(psra_s_i16x4, int16x4_t, >>) -__packed_shift32(psra_s_i32x2, int32x2_t, >>) +/* Packed Shift (32-bit) */ +__packed_binary_builtin_mixed(psll_s_u8x4, uint8x4_t, uint8x4_t, unsigned int, __builtin_riscv_psll_s_u8x4) +__packed_binary_builtin_mixed(psll_s_i8x4, int8x4_t, int8x4_t, unsigned int, __builtin_riscv_psll_s_u8x4) +__packed_binary_builtin_mixed(psll_s_u16x2, uint16x2_t, uint16x2_t, unsigned int, __builtin_riscv_psll_s_u16x2) +__packed_binary_builtin_mixed(psll_s_i16x2, int16x2_t, int16x2_t, unsigned int, __builtin_riscv_psll_s_u16x2) +__packed_binary_builtin_mixed(psrl_s_u8x4, uint8x4_t, uint8x4_t, unsigned int, __builtin_riscv_psrl_s_u8x4) +__packed_binary_builtin_mixed(psrl_s_u16x2, uint16x2_t, uint16x2_t, unsigned int, __builtin_riscv_psrl_s_u16x2) +__packed_binary_builtin_mixed(psra_s_i8x4, int8x4_t, int8x4_t, unsigned int, __builtin_riscv_psra_s_i8x4) +__packed_binary_builtin_mixed(psra_s_i16x2, int16x2_t, int16x2_t, unsigned int, __builtin_riscv_psra_s_i16x2) + +/* Packed Shift (64-bit) */ +__packed_binary_builtin_mixed(psll_s_u8x8, uint8x8_t, uint8x8_t, unsigned int, __builtin_riscv_psll_s_u8x8) +__packed_binary_builtin_mixed(psll_s_i8x8, int8x8_t, int8x8_t, unsigned int, __builtin_riscv_psll_s_u8x8) +__packed_binary_builtin_mixed(psll_s_u16x4, uint16x4_t, uint16x4_t, unsigned int, __builtin_riscv_psll_s_u16x4) +__packed_binary_builtin_mixed(psll_s_i16x4, int16x4_t, int16x4_t, unsigned int, __builtin_riscv_psll_s_u16x4) +__packed_binary_builtin_mixed(psll_s_u32x2, uint32x2_t, uint32x2_t, unsigned int, __builtin_riscv_psll_s_u32x2) +__packed_binary_builtin_mixed(psll_s_i32x2, int32x2_t, int32x2_t, unsigned int, __builtin_riscv_psll_s_u32x2) +__packed_binary_builtin_mixed(psrl_s_u8x8, uint8x8_t, uint8x8_t, unsigned int, __builtin_riscv_psrl_s_u8x8) +__packed_binary_builtin_mixed(psrl_s_u16x4, uint16x4_t, uint16x4_t, unsigned int, __builtin_riscv_psrl_s_u16x4) +__packed_binary_builtin_mixed(psrl_s_u32x2, uint32x2_t, uint32x2_t, unsigned int, __builtin_riscv_psrl_s_u32x2) +__packed_binary_builtin_mixed(psra_s_i8x8, int8x8_t, int8x8_t, unsigned int, __builtin_riscv_psra_s_i8x8) +__packed_binary_builtin_mixed(psra_s_i16x4, int16x4_t, int16x4_t, unsigned int, __builtin_riscv_psra_s_i16x4) +__packed_binary_builtin_mixed(psra_s_i32x2, int32x2_t, int32x2_t, unsigned int, __builtin_riscv_psra_s_i32x2) /* Packed Saturating and Rounding Shifts (32-bit) */ __packed_binary_builtin_mixed(pssha_s_i16x2, int16x2_t, int16x2_t, int, __builtin_riscv_pssha_s_i16x2) @@ -1313,10 +1304,6 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t) #undef __packed_splat4 #undef __packed_splat8 #undef __packed_splat -#undef __packed_shift -#undef __packed_shift8 -#undef __packed_shift16 -#undef __packed_shift32 #undef __packed_scalar_binary_op #undef __packed_binary_op #undef __packed_unary_op diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index 0792df58dbfb4..c24f7971a4aa1 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -4082,25 +4082,17 @@ uint32x2_t test_pmsleu_u32x2(uint32x2_t a, uint32x2_t b) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHL_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psll.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psll_s_i8x4( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHL_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psll.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // int8x4_t test_psll_s_i8x4(int8x4_t a, unsigned shamt) { return __riscv_psll_s_i8x4(a, shamt); @@ -4110,25 +4102,17 @@ int8x4_t test_psll_s_i8x4(int8x4_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHL_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psll.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psll_s_u8x4( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHL_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psll.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // uint8x4_t test_psll_s_u8x4(uint8x4_t a, unsigned shamt) { return __riscv_psll_s_u8x4(a, shamt); @@ -4138,25 +4122,17 @@ uint8x4_t test_psll_s_u8x4(uint8x4_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHL_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psll.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psll_s_i16x2( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHL_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psll.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // int16x2_t test_psll_s_i16x2(int16x2_t a, unsigned shamt) { return __riscv_psll_s_i16x2(a, shamt); @@ -4166,25 +4142,17 @@ int16x2_t test_psll_s_i16x2(int16x2_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHL_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psll.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psll_s_u16x2( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHL_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psll.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // uint16x2_t test_psll_s_u16x2(uint16x2_t a, unsigned shamt) { return __riscv_psll_s_u16x2(a, shamt); @@ -4194,25 +4162,17 @@ uint16x2_t test_psll_s_u16x2(uint16x2_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = ashr <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHR_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psra.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psra_s_i8x4( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = ashr <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHR_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psra.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // int8x4_t test_psra_s_i8x4(int8x4_t a, unsigned shamt) { return __riscv_psra_s_i8x4(a, shamt); @@ -4222,25 +4182,17 @@ int8x4_t test_psra_s_i8x4(int8x4_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = lshr <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHR_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psrl.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psrl_s_u8x4( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <4 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = lshr <4 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i8> [[SHR_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psrl.v4i8(<4 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // uint8x4_t test_psrl_s_u8x4(uint8x4_t a, unsigned shamt) { return __riscv_psrl_s_u8x4(a, shamt); @@ -4250,25 +4202,17 @@ uint8x4_t test_psrl_s_u8x4(uint8x4_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = ashr <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHR_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psra.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psra_s_i16x2( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = ashr <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHR_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psra.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // int16x2_t test_psra_s_i16x2(int16x2_t a, unsigned shamt) { return __riscv_psra_s_i16x2(a, shamt); @@ -4278,25 +4222,17 @@ int16x2_t test_psra_s_i16x2(int16x2_t a, unsigned shamt) { // RV32-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = lshr <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHR_I]] to i32 -// RV32-NEXT: ret i32 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psrl.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] // // RV64-LABEL: define dso_local i32 @test_psrl_s_u16x2( // RV64-SAME: i32 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[A_COERCE]] to <2 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <2 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = lshr <2 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <2 x i16> [[SHR_I]] to i32 -// RV64-NEXT: ret i32 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psrl.v2i16(<2 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] // uint16x2_t test_psrl_s_u16x2(uint16x2_t a, unsigned shamt) { return __riscv_psrl_s_u16x2(a, shamt); @@ -4308,25 +4244,17 @@ uint16x2_t test_psrl_s_u16x2(uint16x2_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psll.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_i8x8( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psll.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int8x8_t test_psll_s_i8x8(int8x8_t a, unsigned shamt) { return __riscv_psll_s_i8x8(a, shamt); @@ -4336,25 +4264,17 @@ int8x8_t test_psll_s_i8x8(int8x8_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psll.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_u8x8( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psll.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint8x8_t test_psll_s_u8x8(uint8x8_t a, unsigned shamt) { return __riscv_psll_s_u8x8(a, shamt); @@ -4364,25 +4284,17 @@ uint8x8_t test_psll_s_u8x8(uint8x8_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psll.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_i16x4( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psll.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int16x4_t test_psll_s_i16x4(int16x4_t a, unsigned shamt) { return __riscv_psll_s_i16x4(a, shamt); @@ -4392,25 +4304,17 @@ int16x4_t test_psll_s_i16x4(int16x4_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psll.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_u16x4( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psll.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint16x4_t test_psll_s_u16x4(uint16x4_t a, unsigned shamt) { return __riscv_psll_s_u16x4(a, shamt); @@ -4420,23 +4324,17 @@ uint16x4_t test_psll_s_u16x4(uint16x4_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV32-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV32-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV32-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP1]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psll.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_i32x2( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV64-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV64-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV64-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP1]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psll.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int32x2_t test_psll_s_i32x2(int32x2_t a, unsigned shamt) { return __riscv_psll_s_i32x2(a, shamt); @@ -4446,23 +4344,17 @@ int32x2_t test_psll_s_i32x2(int32x2_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV32-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV32-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV32-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHL_I:%.*]] = shl <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHL_I]] to i64 -// RV32-NEXT: ret i64 [[TMP1]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psll.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psll_s_u32x2( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV64-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV64-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV64-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHL_I:%.*]] = shl <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHL_I]] to i64 -// RV64-NEXT: ret i64 [[TMP1]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psll.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint32x2_t test_psll_s_u32x2(uint32x2_t a, unsigned shamt) { return __riscv_psll_s_u32x2(a, shamt); @@ -4472,25 +4364,17 @@ uint32x2_t test_psll_s_u32x2(uint32x2_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = ashr <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psra.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psra_s_i8x8( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = ashr <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psra.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int8x8_t test_psra_s_i8x8(int8x8_t a, unsigned shamt) { return __riscv_psra_s_i8x8(a, shamt); @@ -4500,25 +4384,17 @@ int8x8_t test_psra_s_i8x8(int8x8_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV32-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = lshr <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psrl.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psrl_s_u8x8( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <8 x i8> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i8 -// RV64-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], 7 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <8 x i8> poison, i8 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <8 x i8> [[TMP3]], <8 x i8> poison, <8 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = lshr <8 x i8> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <8 x i8> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psrl.v8i8(<8 x i8> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint8x8_t test_psrl_s_u8x8(uint8x8_t a, unsigned shamt) { return __riscv_psrl_s_u8x8(a, shamt); @@ -4528,25 +4404,17 @@ uint8x8_t test_psrl_s_u8x8(uint8x8_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = ashr <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psra.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psra_s_i16x4( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = ashr <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psra.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int16x4_t test_psra_s_i16x4(int16x4_t a, unsigned shamt) { return __riscv_psra_s_i16x4(a, shamt); @@ -4556,25 +4424,17 @@ int16x4_t test_psra_s_i16x4(int16x4_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV32-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV32-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV32-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV32-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = lshr <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV32-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP4]] +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psrl.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psrl_s_u16x4( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <4 x i16> -// RV64-NEXT: [[TMP1:%.*]] = trunc i32 [[SHAMT]] to i16 -// RV64-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 15 -// RV64-NEXT: [[TMP3:%.*]] = insertelement <4 x i16> poison, i16 [[TMP2]], i64 0 -// RV64-NEXT: [[SH_PROM_I:%.*]] = shufflevector <4 x i16> [[TMP3]], <4 x i16> poison, <4 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = lshr <4 x i16> [[TMP0]], [[SH_PROM_I]] -// RV64-NEXT: [[TMP4:%.*]] = bitcast <4 x i16> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP4]] +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psrl.v4i16(<4 x i16> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint16x4_t test_psrl_s_u16x4(uint16x4_t a, unsigned shamt) { return __riscv_psrl_s_u16x4(a, shamt); @@ -4584,23 +4444,17 @@ uint16x4_t test_psrl_s_u16x4(uint16x4_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV32-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV32-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV32-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = ashr <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP1]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psra.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psra_s_i32x2( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV64-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV64-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV64-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = ashr <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP1]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psra.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // int32x2_t test_psra_s_i32x2(int32x2_t a, unsigned shamt) { return __riscv_psra_s_i32x2(a, shamt); @@ -4610,23 +4464,17 @@ int32x2_t test_psra_s_i32x2(int32x2_t a, unsigned shamt) { // RV32-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef [[SHAMT:%.*]]) #[[ATTR0]] { // RV32-NEXT: [[ENTRY:.*:]] // RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV32-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV32-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV32-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV32-NEXT: [[SHR_I:%.*]] = lshr <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV32-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHR_I]] to i64 -// RV32-NEXT: ret i64 [[TMP1]] +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psrl.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] // // RV64-LABEL: define dso_local i64 @test_psrl_s_u32x2( // RV64-SAME: i64 noundef [[A_COERCE:%.*]], i32 noundef signext [[SHAMT:%.*]]) #[[ATTR0]] { // RV64-NEXT: [[ENTRY:.*:]] // RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[A_COERCE]] to <2 x i32> -// RV64-NEXT: [[AND_I:%.*]] = and i32 [[SHAMT]], 31 -// RV64-NEXT: [[SPLAT_SPLATINSERT_I:%.*]] = insertelement <2 x i32> poison, i32 [[AND_I]], i64 0 -// RV64-NEXT: [[SPLAT_SPLAT_I:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT_I]], <2 x i32> poison, <2 x i32> zeroinitializer -// RV64-NEXT: [[SHR_I:%.*]] = lshr <2 x i32> [[TMP0]], [[SPLAT_SPLAT_I]] -// RV64-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[SHR_I]] to i64 -// RV64-NEXT: ret i64 [[TMP1]] +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.riscv.psrl.v2i32(<2 x i32> [[TMP0]], i32 [[SHAMT]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] // uint32x2_t test_psrl_s_u32x2(uint32x2_t a, unsigned shamt) { return __riscv_psrl_s_u32x2(a, shamt); diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 8e2d683b0af69..7312a5f0a57e2 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2076,6 +2076,11 @@ class RVPBinaryIntrinsic def int_riscv_psshl : RVPShiftIntrinsic; def int_riscv_psshlr : RVPShiftIntrinsic; + // Packed Shift. + def int_riscv_psll : RVPShiftIntrinsic; + def int_riscv_psrl : RVPShiftIntrinsic; + def int_riscv_psra : RVPShiftIntrinsic; + // Packed Exchanged Addition and Subtraction. def int_riscv_pas : RVPBinaryIntrinsic; def int_riscv_psa : RVPBinaryIntrinsic; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 5534eac885d9e..d45bd4e8c1d60 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9557,7 +9557,7 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op, default: llvm_unreachable("Unexpected opcode"); case ISD::SHL: - Opc = RISCVISD::PSHL; + Opc = RISCVISD::PSLL; break; case ISD::SRL: Opc = RISCVISD::PSRL; @@ -12316,6 +12316,12 @@ static unsigned getRVPShiftOpcode(Intrinsic::ID IntNo) { default: llvm_unreachable( "Unexpected RISC-V packed saturating and rounding shift intrinsic"); + case Intrinsic::riscv_psll: + return RISCVISD::PSLL; + case Intrinsic::riscv_psrl: + return RISCVISD::PSRL; + case Intrinsic::riscv_psra: + return RISCVISD::PSRA; case Intrinsic::riscv_pssha: return RISCVISD::PSSHA; case Intrinsic::riscv_psshar: @@ -13149,6 +13155,9 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, return DAG.getNode(Opc, DL, VT, Rs1, Rs2); } + case Intrinsic::riscv_psll: + case Intrinsic::riscv_psrl: + case Intrinsic::riscv_psra: case Intrinsic::riscv_pssha: case Intrinsic::riscv_psshar: case Intrinsic::riscv_psshl: @@ -17792,15 +17801,18 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, } return; } + case Intrinsic::riscv_psll: + case Intrinsic::riscv_psrl: + case Intrinsic::riscv_psra: case Intrinsic::riscv_pssha: case Intrinsic::riscv_psshar: case Intrinsic::riscv_psshl: case Intrinsic::riscv_psshlr: { MVT VT = N->getSimpleValueType(0); - if (!Subtarget.is64Bit() || VT != MVT::v2i16) + if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16)) return; - MVT WideVT = MVT::v4i16; + EVT WideVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16; SDValue Op0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(1), DAG.getUNDEF(VT)); SDValue ShAmt = N->getOperand(2); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 24096ab7d4a50..a5251633c493f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -2056,7 +2056,7 @@ def riscv_mulqr : RVSDNode<"MULQR", SDTIntBinOp, [SDNPCommutative]>; def SDT_RISCVPackedShift : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVT<2, XLenVT>]>; -def riscv_pshl : RVSDNode<"PSHL", SDT_RISCVPackedShift>; +def riscv_psll : RVSDNode<"PSLL", SDT_RISCVPackedShift>; def riscv_psrl : RVSDNode<"PSRL", SDT_RISCVPackedShift>; def riscv_psra : RVSDNode<"PSRA", SDT_RISCVPackedShift>; def riscv_pssha : RVSDNode<"PSSHA", SDT_RISCVPackedShift>; @@ -2184,10 +2184,10 @@ class PatHorizontalMul<SDPatternOperator OpNode, RVInst Inst, // (rs1 << 1) + rs2 class PatPSh1Add<RVInst Inst, ValueType vt> - : Pat<(vt (add (riscv_pshl (vt GPR:$rs1), (XLenVT 1)), (vt GPR:$rs2))), + : Pat<(vt (add (riscv_psll (vt GPR:$rs1), (XLenVT 1)), (vt GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>; class PatPSh1AddPair<RVInst Inst, ValueType vt> - : Pat<(vt (add (riscv_pshl (vt GPRPair:$rs1), (XLenVT 1)), (vt GPRPair:$rs2))), + : Pat<(vt (add (riscv_psll (vt GPRPair:$rs1), (XLenVT 1)), (vt GPRPair:$rs2))), (Inst GPRPair:$rs1, GPRPair:$rs2)>; // Vector sshlsat is custom-lowered to riscv_pssha before isel; saddsat(a, a) @@ -2335,11 +2335,11 @@ let Predicates = [HasStdExtP] in { def : PatGprGpr<riscv_mulqr, PMULQR_H, XLenVecI16VT>; // 8-bit logical shift left/right patterns - def : PatGprImm<riscv_pshl, PSLLI_B, uimm3, XLenVecI8VT>; + def : PatGprImm<riscv_psll, PSLLI_B, uimm3, XLenVecI8VT>; def : PatGprImm<riscv_psrl, PSRLI_B, uimm3, XLenVecI8VT>; // 16-bit logical shift left/right patterns - def : PatGprImm<riscv_pshl, PSLLI_H, uimm4, XLenVecI16VT>; + def : PatGprImm<riscv_psll, PSLLI_H, uimm4, XLenVecI16VT>; def : PatGprImm<riscv_psrl, PSRLI_H, uimm4, XLenVecI16VT>; // 8-bit arithmetic shift right patterns @@ -2359,14 +2359,14 @@ let Predicates = [HasStdExtP] in { def : PatGprShift<riscv_psshlr, PSSHLR_HS, XLenVecI16VT>; // 8-bit logical shift left/right - def : PatGprShiftMask<riscv_pshl, PSLL_BS, shiftMask32, XLenVecI8VT>; + def : PatGprShiftMask<riscv_psll, PSLL_BS, shiftMask32, XLenVecI8VT>; def : PatGprShiftMask<riscv_psrl, PSRL_BS, shiftMask32, XLenVecI8VT>; // 8-bit arithmetic shift left/right def : PatGprShiftMask<riscv_psra, PSRA_BS, shiftMask32, XLenVecI8VT>; // 16-bit logical shift left/right - def : PatGprShiftMask<riscv_pshl, PSLL_HS, shiftMask32, XLenVecI16VT>; + def : PatGprShiftMask<riscv_psll, PSLL_HS, shiftMask32, XLenVecI16VT>; def : PatGprShiftMask<riscv_psrl, PSRL_HS, shiftMask32, XLenVecI16VT>; // 16-bit arithmetic shift left/right @@ -2829,15 +2829,15 @@ let append Predicates = [IsRV32] in { def : PatGprPairGprPair<abdu, PABDU_DH, v4i16>; // 8-bit logical shift left/right patterns - def : PatGprPairImm<riscv_pshl, PSLLI_DB, uimm3, v8i8>; + def : PatGprPairImm<riscv_psll, PSLLI_DB, uimm3, v8i8>; def : PatGprPairImm<riscv_psrl, PSRLI_DB, uimm3, v8i8>; // 16-bit logical shift left/right patterns - def : PatGprPairImm<riscv_pshl, PSLLI_DH, uimm4, v4i16>; + def : PatGprPairImm<riscv_psll, PSLLI_DH, uimm4, v4i16>; def : PatGprPairImm<riscv_psrl, PSRLI_DH, uimm4, v4i16>; // 32-bit logical shift left/right patterns - def : PatGprPairImm<riscv_pshl, PSLLI_DW, uimm5, v2i32>; + def : PatGprPairImm<riscv_psll, PSLLI_DW, uimm5, v2i32>; def : PatGprPairImm<riscv_psrl, PSRLI_DW, uimm5, v2i32>; // 8-bit arithmetic shift right patterns @@ -2870,21 +2870,21 @@ let append Predicates = [IsRV32] in { def : PatGprPairShift<riscv_psshlr, PSSHLR_DWS, v2i32>; // 8-bit logical shift left/right - def : PatGprPairShiftMask<riscv_pshl, PSLL_DBS, shiftMask32, v8i8>; + def : PatGprPairShiftMask<riscv_psll, PSLL_DBS, shiftMask32, v8i8>; def : PatGprPairShiftMask<riscv_psrl, PSRL_DBS, shiftMask32, v8i8>; // 8-bit arithmetic shift left/right def : PatGprPairShiftMask<riscv_psra, PSRA_DBS, shiftMask32, v8i8>; // 16-bit logical shift left/right - def : PatGprPairShiftMask<riscv_pshl, PSLL_DHS, shiftMask32, v4i16>; + def : PatGprPairShiftMask<riscv_psll, PSLL_DHS, shiftMask32, v4i16>; def : PatGprPairShiftMask<riscv_psrl, PSRL_DHS, shiftMask32, v4i16>; // 16-bit arithmetic shift left/right def : PatGprPairShiftMask<riscv_psra, PSRA_DHS, shiftMask32, v4i16>; // 32-bit logical shift left/right - def : PatGprPairShiftMask<riscv_pshl, PSLL_DWS, shiftMask32, v2i32>; + def : PatGprPairShiftMask<riscv_psll, PSLL_DWS, shiftMask32, v2i32>; def : PatGprPairShiftMask<riscv_psrl, PSRL_DWS, shiftMask32, v2i32>; // 32-bit arithmetic shift left/right @@ -3312,7 +3312,7 @@ let append Predicates = [IsRV64] in { (PM2ADDAU_H GPR:$rd, GPR:$rs1, GPR:$rs2)>; // 32-bit logical shift left/right patterns - def : PatGprImm<riscv_pshl, PSLLI_W, uimm5, v2i32>; + def : PatGprImm<riscv_psll, PSLLI_W, uimm5, v2i32>; def : PatGprImm<riscv_psrl, PSRLI_W, uimm5, v2i32>; // 32-bit arithmetic shift left/right patterns @@ -3329,7 +3329,7 @@ let append Predicates = [IsRV64] in { def : PatGprShift<riscv_psshlr, PSSHLR_WS, v2i32>; // 32-bit logical shift left/right - def : PatGprShiftMask<riscv_pshl, PSLL_WS, shiftMask32, v2i32>; + def : PatGprShiftMask<riscv_psll, PSLL_WS, shiftMask32, v2i32>; def : PatGprShiftMask<riscv_psrl, PSRL_WS, shiftMask32, v2i32>; // 32-bit arithmetic shift left/right diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll index af06335875e65..2335628942527 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll @@ -1263,6 +1263,60 @@ define <4 x i8> @test_psra_bs_vec_shamt(<4 x i8> %a, <4 x i8> %b) { ret <4 x i8> %res } +define <4 x i8> @test_psll_s_u8x4(<4 x i8> %a, i32 %shamt) { +; CHECK-LABEL: test_psll_s_u8x4: +; CHECK: # %bb.0: +; CHECK-NEXT: psll.bs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <4 x i8> @llvm.riscv.psll.v4i8(<4 x i8> %a, i32 %shamt) + ret <4 x i8> %res +} + +define <2 x i16> @test_psll_s_u16x2(<2 x i16> %a, i32 %shamt) { +; CHECK-LABEL: test_psll_s_u16x2: +; CHECK: # %bb.0: +; CHECK-NEXT: psll.hs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.psll.v2i16(<2 x i16> %a, i32 %shamt) + ret <2 x i16> %res +} + +define <4 x i8> @test_psrl_s_u8x4(<4 x i8> %a, i32 %shamt) { +; CHECK-LABEL: test_psrl_s_u8x4: +; CHECK: # %bb.0: +; CHECK-NEXT: psrl.bs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <4 x i8> @llvm.riscv.psrl.v4i8(<4 x i8> %a, i32 %shamt) + ret <4 x i8> %res +} + +define <2 x i16> @test_psrl_s_u16x2(<2 x i16> %a, i32 %shamt) { +; CHECK-LABEL: test_psrl_s_u16x2: +; CHECK: # %bb.0: +; CHECK-NEXT: psrl.hs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.psrl.v2i16(<2 x i16> %a, i32 %shamt) + ret <2 x i16> %res +} + +define <4 x i8> @test_psra_s_i8x4(<4 x i8> %a, i32 %shamt) { +; CHECK-LABEL: test_psra_s_i8x4: +; CHECK: # %bb.0: +; CHECK-NEXT: psra.bs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <4 x i8> @llvm.riscv.psra.v4i8(<4 x i8> %a, i32 %shamt) + ret <4 x i8> %res +} + +define <2 x i16> @test_psra_s_i16x2(<2 x i16> %a, i32 %shamt) { +; CHECK-LABEL: test_psra_s_i16x2: +; CHECK: # %bb.0: +; CHECK-NEXT: psra.hs a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.psra.v2i16(<2 x i16> %a, i32 %shamt) + ret <2 x i16> %res +} + ; Packed saturating and rounding shifts define <2 x i16> @test_pssha_s_i16x2(<2 x i16> %a, i32 %shamt) { ; CHECK-LABEL: test_pssha_s_i16x2: @@ -2554,10 +2608,10 @@ define <2 x i16> @test_select_v2i16(i1 %cond, <2 x i16> %a, <2 x i16> %b) { ; CHECK: # %bb.0: ; CHECK-NEXT: andi a3, a0, 1 ; CHECK-NEXT: mv a0, a1 -; CHECK-NEXT: bnez a3, [[SELECT_BB:.LBB[0-9]+_2]] +; CHECK-NEXT: bnez a3, .LBB184_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: mv a0, a2 -; CHECK-NEXT: [[SELECT_BB]]: +; CHECK-NEXT: .LBB184_2: ; CHECK-NEXT: ret %res = select i1 %cond, <2 x i16> %a, <2 x i16> %b ret <2 x i16> %res @@ -2568,10 +2622,10 @@ define <4 x i8> @test_select_v4i8(i1 %cond, <4 x i8> %a, <4 x i8> %b) { ; CHECK: # %bb.0: ; CHECK-NEXT: andi a3, a0, 1 ; CHECK-NEXT: mv a0, a1 -; CHECK-NEXT: bnez a3, [[SELECT_BB:.LBB[0-9]+_2]] +; CHECK-NEXT: bnez a3, .LBB185_2 ; CHECK-NEXT: # %bb.1: ; CHECK-NEXT: mv a0, a2 -; CHECK-NEXT: [[SELECT_BB]]: +; CHECK-NEXT: .LBB185_2: ; CHECK-NEXT: ret %res = select i1 %cond, <4 x i8> %a, <4 x i8> %b ret <4 x i8> %res diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll index 9ac7b5ff4cf2e..644b1a4c2d2a6 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -2314,6 +2314,132 @@ define <2 x i32> @test_psra_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) { ret <2 x i32> %res } +define <8 x i8> @test_psll_s_u8x8(<8 x i8> %a, i32 %shamt) { +; RV32-LABEL: test_psll_s_u8x8: +; RV32: # %bb.0: +; RV32-NEXT: psll.dbs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psll_s_u8x8: +; RV64: # %bb.0: +; RV64-NEXT: psll.bs a0, a0, a1 +; RV64-NEXT: ret + %res = call <8 x i8> @llvm.riscv.psll.v8i8(<8 x i8> %a, i32 %shamt) + ret <8 x i8> %res +} + +define <4 x i16> @test_psll_s_u16x4(<4 x i16> %a, i32 %shamt) { +; RV32-LABEL: test_psll_s_u16x4: +; RV32: # %bb.0: +; RV32-NEXT: psll.dhs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psll_s_u16x4: +; RV64: # %bb.0: +; RV64-NEXT: psll.hs a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.psll.v4i16(<4 x i16> %a, i32 %shamt) + ret <4 x i16> %res +} + +define <2 x i32> @test_psll_s_u32x2(<2 x i32> %a, i32 %shamt) { +; RV32-LABEL: test_psll_s_u32x2: +; RV32: # %bb.0: +; RV32-NEXT: psll.dws a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psll_s_u32x2: +; RV64: # %bb.0: +; RV64-NEXT: psll.ws a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.psll.v2i32(<2 x i32> %a, i32 %shamt) + ret <2 x i32> %res +} + +define <8 x i8> @test_psrl_s_u8x8(<8 x i8> %a, i32 %shamt) { +; RV32-LABEL: test_psrl_s_u8x8: +; RV32: # %bb.0: +; RV32-NEXT: psrl.dbs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psrl_s_u8x8: +; RV64: # %bb.0: +; RV64-NEXT: psrl.bs a0, a0, a1 +; RV64-NEXT: ret + %res = call <8 x i8> @llvm.riscv.psrl.v8i8(<8 x i8> %a, i32 %shamt) + ret <8 x i8> %res +} + +define <4 x i16> @test_psrl_s_u16x4(<4 x i16> %a, i32 %shamt) { +; RV32-LABEL: test_psrl_s_u16x4: +; RV32: # %bb.0: +; RV32-NEXT: psrl.dhs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psrl_s_u16x4: +; RV64: # %bb.0: +; RV64-NEXT: psrl.hs a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.psrl.v4i16(<4 x i16> %a, i32 %shamt) + ret <4 x i16> %res +} + +define <2 x i32> @test_psrl_s_u32x2(<2 x i32> %a, i32 %shamt) { +; RV32-LABEL: test_psrl_s_u32x2: +; RV32: # %bb.0: +; RV32-NEXT: psrl.dws a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psrl_s_u32x2: +; RV64: # %bb.0: +; RV64-NEXT: psrl.ws a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.psrl.v2i32(<2 x i32> %a, i32 %shamt) + ret <2 x i32> %res +} + +define <8 x i8> @test_psra_s_i8x8(<8 x i8> %a, i32 %shamt) { +; RV32-LABEL: test_psra_s_i8x8: +; RV32: # %bb.0: +; RV32-NEXT: psra.dbs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psra_s_i8x8: +; RV64: # %bb.0: +; RV64-NEXT: psra.bs a0, a0, a1 +; RV64-NEXT: ret + %res = call <8 x i8> @llvm.riscv.psra.v8i8(<8 x i8> %a, i32 %shamt) + ret <8 x i8> %res +} + +define <4 x i16> @test_psra_s_i16x4(<4 x i16> %a, i32 %shamt) { +; RV32-LABEL: test_psra_s_i16x4: +; RV32: # %bb.0: +; RV32-NEXT: psra.dhs a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psra_s_i16x4: +; RV64: # %bb.0: +; RV64-NEXT: psra.hs a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.psra.v4i16(<4 x i16> %a, i32 %shamt) + ret <4 x i16> %res +} + +define <2 x i32> @test_psra_s_i32x2(<2 x i32> %a, i32 %shamt) { +; RV32-LABEL: test_psra_s_i32x2: +; RV32: # %bb.0: +; RV32-NEXT: psra.dws a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psra_s_i32x2: +; RV64: # %bb.0: +; RV64-NEXT: psra.ws a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.psra.v2i32(<2 x i32> %a, i32 %shamt) + ret <2 x i32> %res +} + ; Packed saturating and rounding shifts define <4 x i16> @test_pssha_s_i16x4(<4 x i16> %a, i32 %shamt) { ; RV32-LABEL: test_pssha_s_i16x4: @@ -4657,12 +4783,12 @@ define <4 x i16> @test_select_v4i16(i1 %cond, <4 x i16> %a, <4 x i16> %b) { ; RV32-LABEL: test_select_v4i16: ; RV32: # %bb.0: ; RV32-NEXT: andi a5, a0, 1 -; RV32-NEXT: bnez a5, .LBB246_2 +; RV32-NEXT: bnez a5, .LBB255_2 ; RV32-NEXT: # %bb.1: ; RV32-NEXT: mv a0, a3 ; RV32-NEXT: mv a1, a4 ; RV32-NEXT: ret -; RV32-NEXT: .LBB246_2: +; RV32-NEXT: .LBB255_2: ; RV32-NEXT: mv a0, a1 ; RV32-NEXT: mv a1, a2 ; RV32-NEXT: ret @@ -4671,10 +4797,10 @@ define <4 x i16> @test_select_v4i16(i1 %cond, <4 x i16> %a, <4 x i16> %b) { ; RV64: # %bb.0: ; RV64-NEXT: andi a3, a0, 1 ; RV64-NEXT: mv a0, a1 -; RV64-NEXT: bnez a3, .LBB246_2 +; RV64-NEXT: bnez a3, .LBB255_2 ; RV64-NEXT: # %bb.1: ; RV64-NEXT: mv a0, a2 -; RV64-NEXT: .LBB246_2: +; RV64-NEXT: .LBB255_2: ; RV64-NEXT: ret %res = select i1 %cond, <4 x i16> %a, <4 x i16> %b ret <4 x i16> %res @@ -4684,12 +4810,12 @@ define <8 x i8> @test_select_v8i8(i1 %cond, <8 x i8> %a, <8 x i8> %b) { ; RV32-LABEL: test_select_v8i8: ; RV32: # %bb.0: ; RV32-NEXT: andi a5, a0, 1 -; RV32-NEXT: bnez a5, .LBB247_2 +; RV32-NEXT: bnez a5, .LBB256_2 ; RV32-NEXT: # %bb.1: ; RV32-NEXT: mv a0, a3 ; RV32-NEXT: mv a1, a4 ; RV32-NEXT: ret -; RV32-NEXT: .LBB247_2: +; RV32-NEXT: .LBB256_2: ; RV32-NEXT: mv a0, a1 ; RV32-NEXT: mv a1, a2 ; RV32-NEXT: ret @@ -4698,10 +4824,10 @@ define <8 x i8> @test_select_v8i8(i1 %cond, <8 x i8> %a, <8 x i8> %b) { ; RV64: # %bb.0: ; RV64-NEXT: andi a3, a0, 1 ; RV64-NEXT: mv a0, a1 -; RV64-NEXT: bnez a3, .LBB247_2 +; RV64-NEXT: bnez a3, .LBB256_2 ; RV64-NEXT: # %bb.1: ; RV64-NEXT: mv a0, a2 -; RV64-NEXT: .LBB247_2: +; RV64-NEXT: .LBB256_2: ; RV64-NEXT: ret %res = select i1 %cond, <8 x i8> %a, <8 x i8> %b ret <8 x i8> %res @@ -4711,12 +4837,12 @@ define <2 x i32> @test_select_v2i32(i1 %cond, <2 x i32> %a, <2 x i32> %b) { ; RV32-LABEL: test_select_v2i32: ; RV32: # %bb.0: ; RV32-NEXT: andi a5, a0, 1 -; RV32-NEXT: bnez a5, .LBB248_2 +; RV32-NEXT: bnez a5, .LBB257_2 ; RV32-NEXT: # %bb.1: ; RV32-NEXT: mv a0, a3 ; RV32-NEXT: mv a1, a4 ; RV32-NEXT: ret -; RV32-NEXT: .LBB248_2: +; RV32-NEXT: .LBB257_2: ; RV32-NEXT: mv a0, a1 ; RV32-NEXT: mv a1, a2 ; RV32-NEXT: ret @@ -4725,10 +4851,10 @@ define <2 x i32> @test_select_v2i32(i1 %cond, <2 x i32> %a, <2 x i32> %b) { ; RV64: # %bb.0: ; RV64-NEXT: andi a3, a0, 1 ; RV64-NEXT: mv a0, a1 -; RV64-NEXT: bnez a3, .LBB248_2 +; RV64-NEXT: bnez a3, .LBB257_2 ; RV64-NEXT: # %bb.1: ; RV64-NEXT: mv a0, a2 -; RV64-NEXT: .LBB248_2: +; RV64-NEXT: .LBB257_2: ; RV64-NEXT: ret %res = select i1 %cond, <2 x i32> %a, <2 x i32> %b ret <2 x i32> %res @@ -4776,16 +4902,16 @@ define <2 x i32> @test_vselect_v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { ; RV32: # %bb.0: ; RV32-NEXT: pmslt.dw a6, a2, a0 ; RV32-NEXT: mv a0, a4 -; RV32-NEXT: beqz a7, .LBB251_3 +; RV32-NEXT: beqz a7, .LBB260_3 ; RV32-NEXT: # %bb.1: -; RV32-NEXT: beqz a6, .LBB251_4 -; RV32-NEXT: .LBB251_2: +; RV32-NEXT: beqz a6, .LBB260_4 +; RV32-NEXT: .LBB260_2: ; RV32-NEXT: mv a1, a5 ; RV32-NEXT: ret -; RV32-NEXT: .LBB251_3: +; RV32-NEXT: .LBB260_3: ; RV32-NEXT: mv a5, a3 -; RV32-NEXT: bnez a6, .LBB251_2 -; RV32-NEXT: .LBB251_4: +; RV32-NEXT: bnez a6, .LBB260_2 +; RV32-NEXT: .LBB260_4: ; RV32-NEXT: mv a0, a2 ; RV32-NEXT: mv a1, a5 ; RV32-NEXT: ret >From 94ae411b8a9fcc41e08f6918f7c6fc89f68bf905 Mon Sep 17 00:00:00 2001 From: Craig Topper <[email protected]> Date: Wed, 23 Sep 2026 21:13:49 -0700 Subject: [PATCH 2/2] Apply batched suggestions from code review Co-authored-by: Craig Topper <[email protected]> --- clang/include/clang/Basic/BuiltinsRISCV.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index 046692899b237..e5601eafd371c 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -203,7 +203,7 @@ def paas_x_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int def pasa_x_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>)">; def pasa_x_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>)">; -// Packed Shifts (32-bit) +// Packed Shift (32-bit) def psll_s_u8x4 : RISCVBuiltin<"_Vector<4, unsigned char>(_Vector<4, unsigned char>, unsigned int)">; def psll_s_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned short>, unsigned int)">; def psrl_s_u8x4 : RISCVBuiltin<"_Vector<4, unsigned char>(_Vector<4, unsigned char>, unsigned int)">; @@ -211,7 +211,7 @@ def psrl_s_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned def psra_s_i8x4 : RISCVBuiltin<"_Vector<4, signed char>(_Vector<4, signed char>, unsigned int)">; def psra_s_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, unsigned int)">; -// Packed Shifts (64-bit) +// Packed Shift (64-bit) def psll_s_u8x8 : RISCVBuiltin<"_Vector<8, unsigned char>(_Vector<8, unsigned char>, unsigned int)">; def psll_s_u16x4 : RISCVBuiltin<"_Vector<4, unsigned short>(_Vector<4, unsigned short>, unsigned int)">; def psll_s_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, unsigned int)">; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
