get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2226866/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226866,
    "url": "http://patchwork.ozlabs.org/api/patches/2226866/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.6@forge-stage.sourceware.org/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.6@forge-stage.sourceware.org>",
    "list_archive_url": null,
    "date": "2026-04-22T19:01:40",
    "name": "[v2,06/14] arm: add support for out of range shift amount in MVE asrl and lsll [PR122216]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "57c0e245dddc2d1a232f78de5242337b14618dcf",
    "submitter": {
        "id": 92734,
        "url": "http://patchwork.ozlabs.org/api/people/92734/?format=api",
        "name": "Christophe Lyon via Sourceware Forge",
        "email": "forge-bot+clyon@forge-stage.sourceware.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.6@forge-stage.sourceware.org/mbox/",
    "series": [
        {
            "id": 501104,
            "url": "http://patchwork.ozlabs.org/api/series/501104/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501104",
            "date": "2026-04-22T19:01:35",
            "name": "arm: [MVE intrinsics] rework vpnot, vgetq_lane, vsetq_lane, vuninitialized and scalar shifts",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/501104/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226866/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226866/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org",
            "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g1BFj6xV0z1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 06:50:48 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 2D7824534562\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 20:36:33 +0000 (GMT)",
            "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 7C68243631DA\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 19:02:48 +0000 (GMT)",
            "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id 87ECC4360C;\n Wed, 22 Apr 2026 19:02:46 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 2D7824534562",
            "OpenDKIM Filter v2.11.0 sourceware.org 7C68243631DA"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 7C68243631DA",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 7C68243631DA",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776884568; cv=none;\n b=x7AdrD7n5y6b2VcjeGSeRYxmyHIxHX6X9q6Cb1YF9fU0wGRuqoYcUJTLGyMqi9wv6DDyUk/PLkUq+D74Cl/vEhuUkyRIJZMq4/hdXWW2EyLZXxUYtsq4tALvG9/O0eTtZ3BGrRJiCpjcC+Q8DuvRnBMbNdlKtRVaDZT31OOmv3E=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776884568; c=relaxed/simple;\n bh=RLRuzdC0P3B9Misdpup3z3lOsLEI+MvX8TYq91vXSpE=;\n h=From:Date:Subject:To:Message-ID;\n b=nCNWp+xZVUgiuuwaxFi1L8IXy6rq8F+Bwg9JlN4G0iEfKRi+hfiUQQiBHn0Q/lQcYcp7VWI1qvaT+BG0uGvuejZHi4liH6kNUgoqcQDKOnCWZ9TptpSdc5saMtWlOaBDdX7nMl2jGj2Z+vFB7MY15va4igKVLDr4+iE05RVZjWE=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "From": "Christophe Lyon via Sourceware Forge\n <forge-bot+clyon@forge-stage.sourceware.org>",
        "Date": "Wed, 22 Apr 2026 19:01:40 +0000",
        "Subject": "[PATCH v2 06/14] arm: add support for out of range shift amount in\n MVE asrl and lsll [PR122216]",
        "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>",
        "Cc": "sloosemore@baylibre.com",
        "Message-ID": "\n <bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.6@forge-stage.sourceware.org>",
        "X-Mailer": "batrachomyomachia",
        "X-Pull-Request-Organization": "gcc",
        "X-Pull-Request-Repository": "gcc-TEST",
        "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/121",
        "References": "\n <bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.0@forge-stage.sourceware.org>",
        "In-Reply-To": "\n <bmm.hhuph3sz8c.gcc.gcc-TEST.clyon.121.2.0@forge-stage.sourceware.org>",
        "X-Patch-URL": "\n https://forge.sourceware.org/clyon/gcc-TEST/commit/41c9e3192df99bcca358433e836375ee9a7e5322",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n sloosemore@baylibre.com, clyon@gcc.gnu.org",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: Christophe Lyon <christophe.lyon@linaro.org>\n\nMVE asrl and lsll instructions have two variants:\n- immediate shift amount in the [1..32] range\n- shift amount in a register, where negative values reverse the\n  direction of the shift\n\nHowever, RTL assumes that the shift amount is interpreted unsigned, so\nwe want to make sure undesired simplifications do not take place.\nFor instance if simplify_rtx optimizes\n(set (reg:SI 1) (const_int -5))\n(set (reg:DI 2) (ashift:DI (reg:DI 3) (reg:SI 1)))\ninto:\n(set (reg:DI 2) (ashift:DI (reg:DI 3) (const_int -5)))\nwe do not want this to be interpreted as undefined behavior.\n\nWe handle this using a general pattern where:\n- immediates are handled by a define_insn_and_split pattern which\n  directly maps immediates in [1..32] to the shift operator and splits\n  other cases as needed.\n- non-immediates are handled by another pattern\n\ngcc/ChangeLog:\n\n\tPR target/122216\n\t* config/arm/arm.md (ashldi3, ashrdi3): Force shift amount into\n\tQImode.\n\t* config/arm/constraints.md: Fix comment, Pg is valid in Thumb-2\n\tstate only.\n\t* config/arm/mve.md (mve_asrl): Handle various shift amount ranges.\n\t(mve_asrl_imm, mve_asrl_internal): New patterns.\n\t(mve_lsll): Handle various shift amount ranges.\n\t(mve_lsll_imm, mve_lsll_internal): New patterns.\n\ngcc/testsuite/ChangeLog:\n\n\tPR target/122216\n\t* gcc.target/arm/mve/intrinsics/asrl-various-ranges.c: New test.\n\t* gcc.target/arm/mve/intrinsics/lsll-various-ranges.c: New test.\n---\n gcc/config/arm/arm.md                         |   2 +\n gcc/config/arm/constraints.md                 |   5 +-\n gcc/config/arm/mve.md                         | 186 +++++++++++++++++-\n .../arm/mve/intrinsics/asrl-various-ranges.c  | 161 +++++++++++++++\n .../arm/mve/intrinsics/lsll-various-ranges.c  | 160 +++++++++++++++\n 5 files changed, 505 insertions(+), 9 deletions(-)\n create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl-various-ranges.c\n create mode 100644 gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll-various-ranges.c",
    "diff": "diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md\nindex 58f8bde4bd92..24c2c14bf41a 100644\n--- a/gcc/config/arm/arm.md\n+++ b/gcc/config/arm/arm.md\n@@ -4588,6 +4588,7 @@\n       if (arm_reg_or_long_shift_imm (operands[2], GET_MODE (operands[2]))\n \t  && (REG_P (operands[2]) || INTVAL(operands[2]) != 32))\n         {\n+\t  operands[2] = convert_modes (QImode, SImode, operands[2], 0);\n \t  emit_insn (gen_mve_lsll (operands[0], operands[1], operands[2]));\n \t  DONE;\n \t}\n@@ -4624,6 +4625,7 @@\n   if (TARGET_HAVE_MVE && !BYTES_BIG_ENDIAN\n       && arm_reg_or_long_shift_imm (operands[2], GET_MODE (operands[2])))\n     {\n+      operands[2] = convert_modes (QImode, SImode, operands[2], 0);\n       emit_insn (gen_mve_asrl (operands[0], operands[1], operands[2]));\n       DONE;\n     }\ndiff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md\nindex 24743a82356b..86a9e97f5140 100644\n--- a/gcc/config/arm/constraints.md\n+++ b/gcc/config/arm/constraints.md\n@@ -35,9 +35,8 @@\n ;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, DN, Dm, Dl, DL, Do, Dv, Dy, Di,\n ;;\t\t\t Dj, Ds, Dt, Dp, Dz, Tu, Te\n ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe\n-;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz, Rd, Rf, Rb, Ra,\n-;;\t\t     Rg, Ri\n-;; in all states: Pg\n+;; in Thumb-2 state: Ha, Pg, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz, Ra, Rb,\n+;;\t\t     Rd, Rf, Rg, Ri\n \n ;; The following memory constraints have been used:\n ;; in ARM/Thumb-2 state: Uh, Ut, Uv, Un, Um, Us, Uo, Up, Uf, Ux, Ul, Uz\ndiff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md\nindex ccde93e5f344..ba71b279dc32 100644\n--- a/gcc/config/arm/mve.md\n+++ b/gcc/config/arm/mve.md\n@@ -4716,19 +4716,193 @@\n   \"dlstp.<dlstp_elemsize>\\t%|lr, %0\"\n   [(set_attr \"type\" \"mve_misc\")])\n \n+\n+;;\n ;; Scalar shifts\n-(define_insn \"mve_asrl\"\n+;;\n+;; immediate shift amounts have to be in the [1..32] range\n+;;\n+;; shift amounts stored in a register can be negative, in which case\n+;; the shift is reversed (asrl, lsll only)\n+;; since RTL expects shift amounts to be unsigned, make sure the\n+;; negative case is handled, in case simplify_rtx could optimize:\n+;; (set (reg:SI 1) (const_int -5))\n+;; (set (reg:DI 2) (ashift:DI (reg:DI 3) (reg:SI 1)))\n+;; into:\n+;; (set (reg:DI 2) (ashift:DI (reg:DI 3) (const_int -5)))\n+\n+;; General pattern for asrl\n+(define_expand \"mve_asrl\"\n+  [(set (match_operand:DI 0 \"arm_general_register_operand\" \"\")\n+\t(ashiftrt:DI (match_operand:DI 1 \"arm_general_register_operand\" \"\")\n+\t\t     (match_operand:QI 2 \"reg_or_int_operand\" \"\")))]\n+  \"TARGET_HAVE_MVE\"\n+{\n+  rtx amount = operands[2];\n+  if (CONST_INT_P (amount))\n+    {\n+      HOST_WIDE_INT ival = INTVAL (amount);\n+\n+      if (ival >= 0)\n+\t/* Right shift.  */\n+\temit_insn (gen_mve_asrl_imm (operands[0], operands[1], amount));\n+      else\n+\t/* Left shift.  */\n+\temit_insn (gen_mve_lsll_imm (operands[0], operands[1],\n+\t\t\t\t     GEN_INT (-ival)));\n+      DONE;\n+    }\n+\n+  emit_insn (gen_mve_asrl_internal (operands[0], operands[1], operands[2]));\n+  DONE;\n+})\n+\n+;; immediate shift amount\n+;; we have to split the insn if the amount is not in the [1..32] range\n+(define_insn_and_split \"mve_asrl_imm\"\n+  [(set (match_operand:DI 0 \"arm_general_register_operand\" \"=r,r\")\n+\t  (ashiftrt:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0,r\")\n+\t\t       (match_operand:QI 2 \"immediate_operand\" \"Pg,I\")))]\n+  \"TARGET_HAVE_MVE\"\n+  \"asrl%?\\\\t%Q0, %R1, %2\"\n+  \"&& !satisfies_constraint_Pg (operands[2])\"\n+  [(clobber (const_int 0))]\n+  \"\n+  rtx amount = operands[2];\n+  HOST_WIDE_INT ival = INTVAL (amount);\n+\n+  /* shift amount in [1..32] is already handled by the Pg constraint.  */\n+\n+  /* Shift by 0, it is just a move.  */\n+  if (ival == 0)\n+    {\n+      emit_insn (gen_movdi (operands[0], operands[1]));\n+      DONE;\n+    }\n+\n+  /* ival < 0 should have already been handled by mve_asrl. */\n+  gcc_assert (ival > 32);\n+\n+  /* Shift amount above immediate range (ival > 32).\n+     out_hi gets the sign bit\n+     out_lo gets in_hi << (ival - 32) or << 31 if ival >= 64.\n+     If ival >= 64, the result is either 0 or -1, depending on the\n+     input sign.  */\n+  rtx in_hi = gen_highpart (SImode, operands[1]);\n+  rtx out_lo = gen_lowpart (SImode, operands[0]);\n+  rtx out_hi = gen_highpart (SImode, operands[0]);\n+\n+  emit_insn (gen_rtx_SET (out_lo,\n+\t\t\t  gen_rtx_fmt_ee (ASHIFTRT,\n+\t\t\t\t\t  SImode,\n+\t\t\t\t\t  in_hi,\n+\t\t\t\t\t  GEN_INT (MIN (ival - 32,\n+\t\t\t\t\t\t\t31)))));\n+  /* Copy sign bit, which is OK even if out_lo == in_hi.  */\n+  emit_insn (gen_rtx_SET (out_hi,\n+\t\t\t  gen_rtx_fmt_ee (ASHIFTRT,\n+\t\t\t\t\t  SImode,\n+\t\t\t\t\t  in_hi,\n+\t\t\t\t\t  GEN_INT (31))));\n+\tDONE;\n+  \"\n+  [(set_attr \"predicable\" \"yes,yes\")\n+   (set_attr \"length\" \"4,8\")])\n+\n+(define_insn \"mve_asrl_internal\"\n   [(set (match_operand:DI 0 \"arm_general_register_operand\" \"=r\")\n-\t(ashiftrt:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0\")\n-\t\t     (match_operand:SI 2 \"arm_reg_or_long_shift_imm\" \"rPg\")))]\n+\t(if_then_else:DI\n+\t  (ge:QI (match_operand:QI 2 \"arm_general_register_operand\" \"r\")\n+\t\t (const_int 0))\n+\t  (ashiftrt:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0\")\n+\t\t       (match_dup 2))\n+\t  (ashift:DI (match_dup 1) (neg:QI (match_dup 2)))))]\n   \"TARGET_HAVE_MVE\"\n   \"asrl%?\\\\t%Q0, %R1, %2\"\n   [(set_attr \"predicable\" \"yes\")])\n \n-(define_insn \"mve_lsll\"\n+;; General pattern for lsll\n+(define_expand \"mve_lsll\"\n+  [(set (match_operand:DI 0 \"arm_general_register_operand\" \"\")\n+\t(ashift:DI (match_operand:DI 1 \"arm_general_register_operand\" \"\")\n+\t\t   (match_operand:QI 2 \"reg_or_int_operand\" \"\")))]\n+  \"TARGET_HAVE_MVE\"\n+{\n+  rtx amount = operands[2];\n+  if (CONST_INT_P (amount))\n+    {\n+      HOST_WIDE_INT ival = INTVAL (amount);\n+\n+      if (ival >= 0)\n+\t/* Left shift.  */\n+\temit_insn (gen_mve_lsll_imm (operands[0], operands[1], amount));\n+      else\n+\t/* Right shift.  */\n+\temit_insn (gen_lshrdi3 (operands[0], operands[1],\n+                                GEN_INT (-ival)));\n+      DONE;\n+    }\n+\n+  emit_insn (gen_mve_lsll_internal (operands[0], operands[1], operands[2]));\n+  DONE;\n+})\n+\n+;; immediate shift amount\n+;; we have to split the insn if the amount is not in the [1..32] range\n+(define_insn_and_split \"mve_lsll_imm\"\n+  [(set (match_operand:DI 0 \"arm_general_register_operand\" \"=r,r\")\n+\t  (ashift:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0,r\")\n+\t\t     (match_operand:QI 2 \"immediate_operand\" \"Pg,I\")))]\n+  \"TARGET_HAVE_MVE\"\n+  \"lsll%?\\\\t%Q0, %R1, %2\"\n+  \"&& !satisfies_constraint_Pg (operands[2])\"\n+  [(clobber (const_int 0))]\n+  \"\n+  rtx amount = operands[2];\n+  HOST_WIDE_INT ival = INTVAL (amount);\n+\n+  /* shift amount in [1..32] is already handled by the Pg constraint.  */\n+\n+  /* Shift by 0, it is just a move.  */\n+  if (ival == 0)\n+    {\n+      emit_insn (gen_movdi (operands[0], operands[1]));\n+      DONE;\n+    }\n+\n+  /* Shift amount larger than input, result is 0.  */\n+  if (ival >= 64)\n+    {\n+      emit_insn (gen_movdi (operands[0], const0_rtx));\n+      DONE;\n+    }\n+\n+  /* ival < 0 should have already been handled by mve_asrl. */\n+  gcc_assert (ival > 32);\n+\n+  /* Shift amount above immediate range: 32 < ival < 64.  */\n+  rtx in_lo = gen_lowpart (SImode, operands[1]);\n+  rtx out_lo = gen_lowpart (SImode, operands[0]);\n+  rtx out_hi = gen_highpart (SImode, operands[0]);\n+  emit_insn (gen_rtx_SET (out_hi,\n+\t\t\t  gen_rtx_fmt_ee (ASHIFT,\n+\t\t\t\t\t  SImode,\n+\t\t\t\t\t  in_lo,\n+\t\t\t\t\t  GEN_INT (ival - 32))));\n+  emit_insn (gen_rtx_SET (out_lo, const0_rtx));\n+  DONE;\n+  \"\n+  [(set_attr \"predicable\" \"yes,yes\")\n+   (set_attr \"length\" \"4,8\")])\n+\n+(define_insn \"mve_lsll_internal\"\n   [(set (match_operand:DI 0 \"arm_general_register_operand\" \"=r\")\n-\t(ashift:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0\")\n-\t\t   (match_operand:SI 2 \"arm_reg_or_long_shift_imm\" \"rPg\")))]\n+        (if_then_else:DI\n+\t  (ge:QI (match_operand:QI 2 \"arm_general_register_operand\" \"r\")\n+\t\t (const_int 0))\n+\t  (ashift:DI (match_operand:DI 1 \"arm_general_register_operand\" \"0\")\n+\t\t     (match_dup 2))\n+\t  (lshiftrt:DI (match_dup 1) (neg:QI (match_dup 2)))))]\n   \"TARGET_HAVE_MVE\"\n   \"lsll%?\\\\t%Q0, %R1, %2\"\n   [(set_attr \"predicable\" \"yes\")])\ndiff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl-various-ranges.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl-various-ranges.c\nnew file mode 100644\nindex 000000000000..4e2a301863d3\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl-various-ranges.c\n@@ -0,0 +1,161 @@\n+/* { dg-require-effective-target arm_v8_1m_mve_ok } */\n+/* { dg-add-options arm_v8_1m_mve } */\n+/* { dg-additional-options \"-O2\" } */\n+/* { dg-final { check-function-bodies \"**\" \"\" } } */\n+\n+/* Check that calling asrl with an out of range shift amount is not interpreted\n+   as undefined behavior, and that we actually use the asrl instruction (except\n+   if a negative shift amount can be handled by lsll).  Check code generation\n+   for various special cases:\n+   1 <= amount <= 32\n+   -32 <= amount <= -1\n+   32 < amount < 64\n+   -64 < amount < -32\n+   amount >= 64\n+   amount <= -64\n+   amount == 0\n+   amount unknown at compile time. */\n+#include \"arm_mve.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+  /* Positive shift amount in [1.32] range, use the immediate:\n+\n+   asrl r0, r1, #3  */\n+/*\n+**foo_3:\n+**\t...\n+**\tasrl\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #3(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_3 (int64_t value)\n+{\n+  return asrl (value, 3);\n+}\n+\n+  /* Negative shift amount in [-32.-1] range, reverse shift (lsll) with the\n+     opposite shift amount as immediate:\n+\n+     lsll r0, r1, #3  */\n+/*\n+**foo_m3:\n+**\t...\n+**\tlsll\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #3(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_m3 (int64_t value)\n+{\n+  return asrl (value, -3);\n+}\n+\n+  /* Out of [1.32] range positive shift amount, but < 64.\n+     lo_out = hi_in >> (amount - 32)\n+     hi_out = hi_in >> 31 (to copy the sign bit)\n+\n+     asrs r0, r1, #1\n+     asrs r1, r1, #31   */\n+/*\n+**foo_33:\n+**\t...\n+**\tasrs\t(?:ip|fp|r[0-9]+), (ip|fp|r[0-9]+), #1(?:\t@.*|)\n+**\tasrs\t(?:ip|fp|r[0-9]+), \\1, #31(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_33 (int64_t value)\n+{\n+  return asrl (value, 33);\n+}\n+\n+  /* Out of [-32..-1] range negative shift amount, but > -64. Reverse shift\n+     (lsll equivalent) in [33.64] range:\n+     hi_out = lo_in << (-amount - 32)\n+     lo_out = 0 \n+\n+     lsls r1, r0, #1\n+     movs r0, #0  */\n+/*\n+**foo_m33:\n+**\t...\n+**\tlsls\t(?:ip|fp|r[0-9]+), (ip|fp|r[0-9]+), #1(?:\t@.*|)\n+**\tmovs\t\\1, #0(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_m33 (int64_t value)\n+{\n+  return asrl (value, -33);\n+}\n+\n+  /* Out of range positive shift amount (>= 64)\n+     lo_out = hi_in >> 31 (copy sign bit)\n+     hi_out = hi_in >> 31\n+\n+     asrs r0, r1, #31\n+     mov r1, r0  */\n+/*\n+**foo_65:\n+**\t...\n+**\tasrs\t(ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #31(?:\t@.*|)\n+**\tmov\t(?:ip|fp|r[0-9]+), \\1(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_65 (int64_t value)\n+{\n+  return asrl (value, 65);\n+}\n+\n+  /* Out of range negative shift amount (<= 64), result is 0.\n+\n+   movs r0, #0\n+   movs r1, #0  */\n+/*\n+**foo_m65:\n+**\t...\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_m65 (int64_t value)\n+{\n+  return asrl (value, -65);\n+}\n+\n+  /* shift amount == 0, use a mov, which is optimized out.  */\n+/*\n+**foo_0:\n+**\tbx\tlr\n+**\t...\n+*/\n+int64_t\n+foo_0 (int64_t value)\n+{\n+  return asrl (value, 0);\n+}\n+\n+  /* Unknown shift amount, use the register variant.\n+\n+     asrl r0, r1, r2  */\n+/*\n+**foo_var:\n+**\t...\n+**\tasrl\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?:\t@.*|)\n+**\t...\n+*/\n+int64_t\n+foo_var (int64_t value, int32_t amount)\n+{\n+  return asrl (value, amount);\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+/* { dg-final { scan-assembler-not \"__ARM_undef\" } } */\ndiff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll-various-ranges.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll-various-ranges.c\nnew file mode 100644\nindex 000000000000..1e2f558af888\n--- /dev/null\n+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll-various-ranges.c\n@@ -0,0 +1,160 @@\n+ /* { dg-require-effective-target arm_v8_1m_mve_ok } */\n+/* { dg-add-options arm_v8_1m_mve } */\n+/* { dg-additional-options \"-O2\" } */\n+/* { dg-final { check-function-bodies \"**\" \"\" } } */\n+\n+/* Check that calling lsll with an out of range shift amount is not interpreted\n+   as undefined behavior, and that we actually use the lsll instruction (except\n+   if a negative shift amount can be handled by asrl).  Check code generation\n+   for various special cases:\n+   1 <= amount <= 32\n+   -32 <= amount <= -1\n+   32 < amount < 64\n+   -64 < amount < -32\n+   amount >= 64\n+   amount <= -64\n+   amount == 0\n+   amount unknown at compile time. */\n+#include \"arm_mve.h\"\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+  /* Positive shift amount in [1.32] range, use the immediate:\n+\n+     lsll r0,r1,#3  */\n+/*\n+**foo_3:\n+**\t...\n+**\tlsll\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #3(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_3 (uint64_t value)\n+{\n+  return lsll (value, 3);\n+}\n+\n+  /* Negative shift amount in [-32.-1] range, reverse shift (asrl) with the\n+     opposite shift amount as immediate:\n+\n+     lsrl r0, r1, #3  */\n+/*\n+**foo_m3:\n+**\t...\n+**\tlsrl\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #3(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_m3 (uint64_t value)\n+{\n+  return lsll (value, -3);\n+}\n+\n+  /* Out of [1..32] range positive shift amount, but < 64.\n+     high_out = low_in << (amount - 32) (using lsls, not lsll)\n+     low_out = 0\n+\n+     lsls r1,r0,#1\n+     movs r0, #0  */\n+/*\n+**foo_33:\n+**\t...\n+**\tlsls\t(?:ip|fp|r[0-9]+), (ip|fp|r[0-9]+), #1(?:\t@.*|)\n+**\tmovs\t\\1, #0(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_33 (uint64_t value)\n+{\n+  return lsll (value, 33);\n+}\n+\n+  /* Out of [-32..-1] range negative shift amount, but > -64.  Reverse shift\n+     (lsrl equivalent) in [33..64] range:\n+     lo_out = hi_in >> (amount - 32)\n+     hi_out = 0\n+\n+     lsrs r0, r1, #1\n+     movs r1, #0  */\n+/*\n+**foo_m33:\n+**\t...\n+**\tlsrs\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #1(?:\t@.*|)\n+**\tmovs\t(?:ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_m33 (uint64_t value)\n+{\n+  return lsll (value, -33);\n+}\n+\n+  /* Out of range positive shift amount (>= 64), result is 0.\n+\n+     movs r0, #0\n+     movs r1, #0  */\n+/*\n+**foo_65:\n+**\t...\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_65 (uint64_t value)\n+{\n+  return lsll (value, 65);\n+}\n+\n+  /* Out of range negative shift amount (<= -64), result is 0, because lsll\n+     uses an unsigned input.\n+\n+     movs r0, #0\n+     movs r1, #0  */\n+/*\n+**foo_m65:\n+**\t...\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\tmovs\t(ip|fp|r[0-9]+), #0(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_m65 (uint64_t value)\n+{\n+  return lsll (value, -65);\n+}\n+\n+  /* shift amount == 0, use a mov, which is optimized out.  */\n+/*\n+**foo_0:\n+**\tbx\tlr\n+**\t...\n+*/\n+uint64_t\n+foo_0 (uint64_t value)\n+{\n+  return lsll (value, 0);\n+}\n+\n+  /* Unknown shift amount, use the register variant.\n+\n+   lsll r0, r1, r2  */\n+/*\n+**foo_var:\n+**\t...\n+**\tlsll\t(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+)(?:\t@.*|)\n+**\t...\n+*/\n+uint64_t\n+foo_var (uint64_t value, int32_t amount)\n+{\n+  return lsll (value, amount);\n+}\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+/* { dg-final { scan-assembler-not \"__ARM_undef\" } } */\n",
    "prefixes": [
        "v2",
        "06/14"
    ]
}