The narrow shift-by-immediate instructions (v{s,}srl{r,}ni and
v{s,}sra{r,}ni, including their saturating variants) encode the
shift amount in 4, 5, 6 or 7 bits, depending on the width of the
wider source element: 0..15 for .b.h, 0..31 for .h.w, 0..63 for
.w.d and 0..127 for .d.q.
The machine description constrained the shift amount with
const_uimm8_operand (0..255) for every format, so out-of-range
immediates were accepted and emitted as instructions that the
assembler cannot encode, e.g.
__lsx_vssrlni_b_h (a, b, 20) -> vssrlni.b.h $vr0,$vr1,20
__lsx_vssrlni_d_q (a, b, 200) -> vssrlni.d.q $vr0,$vr1,200
gcc/ChangeLog:
* config/loongarch/simd.md (shiftimm): New mode attribute.
* config/loongarch/lsx.md
(lsx_vsrlni_<lsxfmt>_<dlsxfmt>,
lsx_vsrlrni_<lsxfmt>_<dlsxfmt>,
lsx_vsrani_<lsxfmt>_<dlsxfmt>,
lsx_vsrarni_<lsxfmt>_<dlsxfmt>,
lsx_vssrlni_<lsxfmt>_<dlsxfmt>,
lsx_vssrlni_<lsxfmt_u>_<dlsxfmt>,
lsx_vssrlrni_<lsxfmt>_<dlsxfmt>,
lsx_vssrlrni_<lsxfmt_u>_<dlsxfmt>,
lsx_vssrani_<lsxfmt>_<dlsxfmt>,
lsx_vssrani_<lsxfmt_u>_<dlsxfmt>,
lsx_vssrarni_<lsxfmt>_<dlsxfmt>,
lsx_vssrarni_<lsxfmt_u>_<dlsxfmt>): Use const_<shiftimm>_operand
instead of const_uimm8_operand for the shift amount.
* config/loongarch/lasx.md
(lasx_xvsrlni_<lasxfmt>_<dlasxqfmt>,
lasx_xvsrlrni_<lasxfmt>_<dlasxqfmt>,
lasx_xvsrani_<lasxfmt>_<dlasxqfmt>,
lasx_xvsrarni_<lasxfmt>_<dlasxqfmt>,
lasx_xvssrlni_<lasxfmt>_<dlasxqfmt>,
lasx_xvssrlni_<lasxfmt_u>_<dlasxqfmt>,
lasx_xvssrlrni_<lasxfmt>_<dlasxqfmt>,
lasx_xvssrlrni_<lasxfmt_u>_<dlasxqfmt>,
lasx_xvssrani_<lasxfmt>_<dlasxqfmt>,
lasx_xvssrani_<lasxfmt_u>_<dlasxqfmt>,
lasx_xvssrarni_<lasxfmt>_<dlasxqfmt>,
lasx_xvssrarni_<lasxfmt_u>_<dlasxqfmt>): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/vector/lsx/shift-imm-range.c: New test.
* gcc.target/loongarch/vector/lasx/shift-imm-range.c: New test.
---
gcc/config/loongarch/lasx.md | 24 +--
gcc/config/loongarch/lsx.md | 24 +--
gcc/config/loongarch/simd.md | 9 +
.../loongarch/vector/lasx/shift-imm-range.c | 154 ++++++++++++++++++
.../loongarch/vector/lsx/shift-imm-range.c | 154 ++++++++++++++++++
5 files changed, 341 insertions(+), 24 deletions(-)
create mode 100644
gcc/testsuite/gcc.target/loongarch/vector/lasx/shift-imm-range.c
create mode 100644
gcc/testsuite/gcc.target/loongarch/vector/lsx/shift-imm-range.c
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 23ba70c97dc..fcc087b44e0 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -3214,7 +3214,7 @@ (define_insn "lasx_xvsrlni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSRLNI))]
"ISA_HAS_LASX"
"xvsrlni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3225,7 +3225,7 @@ (define_insn "lasx_xvsrlrni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSRLRNI))]
"ISA_HAS_LASX"
"xvsrlrni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3236,7 +3236,7 @@ (define_insn "lasx_xvssrlni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRLNI))]
"ISA_HAS_LASX"
"xvssrlni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3247,7 +3247,7 @@ (define_insn "lasx_xvssrlni_<lasxfmt_u>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRLNI2))]
"ISA_HAS_LASX"
"xvssrlni.<lasxfmt_u>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3258,7 +3258,7 @@ (define_insn "lasx_xvssrlrni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRLRNI))]
"ISA_HAS_LASX"
"xvssrlrni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3269,7 +3269,7 @@ (define_insn "lasx_xvssrlrni_<lasxfmt_u>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRLRNI2))]
"ISA_HAS_LASX"
"xvssrlrni.<lasxfmt_u>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3280,7 +3280,7 @@ (define_insn "lasx_xvsrani_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSRANI))]
"ISA_HAS_LASX"
"xvsrani.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3291,7 +3291,7 @@ (define_insn "lasx_xvsrarni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSRARNI))]
"ISA_HAS_LASX"
"xvsrarni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3302,7 +3302,7 @@ (define_insn "lasx_xvssrani_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRANI))]
"ISA_HAS_LASX"
"xvssrani.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3313,7 +3313,7 @@ (define_insn "lasx_xvssrani_<lasxfmt_u>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRANI2))]
"ISA_HAS_LASX"
"xvssrani.<lasxfmt_u>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3324,7 +3324,7 @@ (define_insn "lasx_xvssrarni_<lasxfmt>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRARNI))]
"ISA_HAS_LASX"
"xvssrarni.<lasxfmt>.<dlasxqfmt>\t%u0,%u2,%3"
@@ -3335,7 +3335,7 @@ (define_insn "lasx_xvssrarni_<lasxfmt_u>_<dlasxqfmt>"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(unspec:ILASX [(match_operand:ILASX 1 "register_operand" "0")
(match_operand:ILASX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LASX_XVSSRARNI2))]
"ISA_HAS_LASX"
"xvssrarni.<lasxfmt_u>.<dlasxqfmt>\t%u0,%u2,%3"
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index 051ce18bd7e..f08e565a224 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -2984,7 +2984,7 @@ (define_insn "lsx_vsrlni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSRLNI))]
"ISA_HAS_LSX"
"vsrlni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -2995,7 +2995,7 @@ (define_insn "lsx_vsrlrni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSRLRNI))]
"ISA_HAS_LSX"
"vsrlrni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3006,7 +3006,7 @@ (define_insn "lsx_vssrlni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRLNI))]
"ISA_HAS_LSX"
"vssrlni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3017,7 +3017,7 @@ (define_insn "lsx_vssrlni_<lsxfmt_u>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRLNI2))]
"ISA_HAS_LSX"
"vssrlni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3028,7 +3028,7 @@ (define_insn "lsx_vssrlrni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRLRNI))]
"ISA_HAS_LSX"
"vssrlrni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3039,7 +3039,7 @@ (define_insn "lsx_vssrlrni_<lsxfmt_u>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRLRNI2))]
"ISA_HAS_LSX"
"vssrlrni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3050,7 +3050,7 @@ (define_insn "lsx_vsrani_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSRANI))]
"ISA_HAS_LSX"
"vsrani.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3061,7 +3061,7 @@ (define_insn "lsx_vsrarni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSRARNI))]
"ISA_HAS_LSX"
"vsrarni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3072,7 +3072,7 @@ (define_insn "lsx_vssrani_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRANI))]
"ISA_HAS_LSX"
"vssrani.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3083,7 +3083,7 @@ (define_insn "lsx_vssrani_<lsxfmt_u>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRANI2))]
"ISA_HAS_LSX"
"vssrani.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3094,7 +3094,7 @@ (define_insn "lsx_vssrarni_<lsxfmt>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRARNI))]
"ISA_HAS_LSX"
"vssrarni.<lsxfmt>.<dlsxfmt>\t%w0,%w2,%3"
@@ -3105,7 +3105,7 @@ (define_insn "lsx_vssrarni_<lsxfmt_u>_<dlsxfmt>"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(unspec:ILSX [(match_operand:ILSX 1 "register_operand" "0")
(match_operand:ILSX 2 "register_operand" "f")
- (match_operand 3 "const_uimm8_operand" "")]
+ (match_operand 3 "const_<shiftimm>_operand" "")]
UNSPEC_LSX_VSSRARNI2))]
"ISA_HAS_LSX"
"vssrarni.<lsxfmt_u>.<dlsxfmt>\t%w0,%w2,%3"
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index 09e746c56e7..97e22aefc5b 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -195,6 +195,15 @@ (define_mode_attr bitimm [(V16QI "uimm3") (V32QI "uimm3")
(V4SI "uimm5") (V8SI "uimm5")
(V2DI "uimm6") (V4DI "uimm6")])
+;; This attribute is used to form an immediate operand constraint using
+;; "const_<shiftimm>_operand" for the narrowing shift-by-immediate
+;; instructions (vsrl{r,}ni and vsra{r,}ni, including their saturating
+;; variants).
+(define_mode_attr shiftimm [(V16QI "uimm4") (V32QI "uimm4")
+ (V8HI "uimm5") (V16HI "uimm5")
+ (V4SI "uimm6") (V8SI "uimm6")
+ (V2DI "uimm7") (V4DI "uimm7")])
+
(define_int_attr hi_lo [(0 "lo") (1 "hi")])
;; =======================================================================
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lasx/shift-imm-range.c
b/gcc/testsuite/gcc.target/loongarch/vector/lasx/shift-imm-range.c
new file mode 100644
index 00000000000..755a78de20a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lasx/shift-imm-range.c
@@ -0,0 +1,154 @@
+/* Check that out-of-range immediates of the LASX narrowing
+ shift-by-immediate instructions (xv{s,}srl{r,}ni and
+ xv{s,}sra{r,}ni, including their saturating variants) are
+ rejected. These used to be accepted and emitted as instructions
+ that the assembler cannot encode. */
+
+/* { dg-do compile } */
+/* { dg-options "-mlasx" } */
+
+#include <lasxintrin.h>
+
+__m256i
+test_xvsrlni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvsrlni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvsrlrni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvsrlrni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlrni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlrni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrlrni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvsrani (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvsrani_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrani_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrani_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrani_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvsrarni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvsrarni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrarni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrarni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvsrarni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrlni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrlni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrlni_u (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrlni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrlrni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrlrni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrlrni_u (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrlrni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrlrni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrani (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrani_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrani_u (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrani_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrani_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrarni (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrarni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m256i
+test_xvssrarni_u (__m256i a, __m256i b)
+{
+ __m256i r;
+
+ r = __lasx_xvssrarni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lasx_xvssrarni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/vector/lsx/shift-imm-range.c
b/gcc/testsuite/gcc.target/loongarch/vector/lsx/shift-imm-range.c
new file mode 100644
index 00000000000..b53e82cde15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector/lsx/shift-imm-range.c
@@ -0,0 +1,154 @@
+/* Check that out-of-range immediates of the LSX narrowing
+ shift-by-immediate instructions (v{s,}srl{r,}ni and
+ v{s,}sra{r,}ni, including their saturating variants) are
+ rejected. These used to be accepted and emitted as instructions
+ that the assembler cannot encode. */
+
+/* { dg-do compile } */
+/* { dg-options "-mlsx" } */
+
+#include <lsxintrin.h>
+
+__m128i
+test_vsrlni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vsrlni_b_h (a, b, 16); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrlni_h_w (a, b, 32); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrlni_w_d (a, b, 64); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrlni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vsrlrni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vsrlrni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrlrni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrlrni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrlrni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vsrani (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vsrani_b_h (a, b, 16); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrani_h_w (a, b, 32); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrani_w_d (a, b, 64); /* { dg-error "invalid argument to built-in
function" } */
+ r = __lsx_vsrani_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vsrarni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vsrarni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrarni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrarni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vsrarni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrlni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrlni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrlni_u (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrlni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrlrni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrlrni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrlrni_u (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrlrni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrlrni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrani (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrani_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrani_u (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrani_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrani_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrarni (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrarni_b_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_h_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_w_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_d_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
+
+__m128i
+test_vssrarni_u (__m128i a, __m128i b)
+{
+ __m128i r;
+
+ r = __lsx_vssrarni_bu_h (a, b, 16); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_hu_w (a, b, 32); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_wu_d (a, b, 64); /* { dg-error "invalid argument to
built-in function" } */
+ r = __lsx_vssrarni_du_q (a, b, 128); /* { dg-error "invalid argument to
built-in function" } */
+ return r;
+}
--
2.55.0