diff mbox series

vec-lowering: Fix ABSU lowering [PR111285]

Message ID 20241027234106.218194-1-quic_apinski@quicinc.com
State New
Headers show
Series vec-lowering: Fix ABSU lowering [PR111285] | expand

Commit Message

Andrew Pinski Oct. 27, 2024, 11:41 p.m. UTC
ABSU_EXPR lowering incorrectly used the resulting type
for the new expression but in the case of ABSU the resulting
type is an unsigned type and with ABSU is folded away. The fix
is to use a signed type for the expression instead.

Bootstrapped and tested on x86_64-linux-gnu.

	PR middle-end/111285

gcc/ChangeLog:

	* tree-vect-generic.cc (do_unop): Use a signed type for the
	operand if the operation was ABSU_EXPR.

gcc/testsuite/ChangeLog:

	* g++.dg/torture/vect-absu-1.C: New test.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
---
 gcc/testsuite/g++.dg/torture/vect-absu-1.C | 29 ++++++++++++++++++++++
 gcc/tree-vect-generic.cc                   | 10 +++++++-
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/vect-absu-1.C

Comments

Richard Biener Oct. 28, 2024, 8:13 a.m. UTC | #1
On Mon, Oct 28, 2024 at 12:41 AM Andrew Pinski <quic_apinski@quicinc.com> wrote:
>
> ABSU_EXPR lowering incorrectly used the resulting type
> for the new expression but in the case of ABSU the resulting
> type is an unsigned type and with ABSU is folded away. The fix
> is to use a signed type for the expression instead.
>
> Bootstrapped and tested on x86_64-linux-gnu.

OK.

>         PR middle-end/111285
>
> gcc/ChangeLog:
>
>         * tree-vect-generic.cc (do_unop): Use a signed type for the
>         operand if the operation was ABSU_EXPR.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/torture/vect-absu-1.C: New test.
>
> Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
> ---
>  gcc/testsuite/g++.dg/torture/vect-absu-1.C | 29 ++++++++++++++++++++++
>  gcc/tree-vect-generic.cc                   | 10 +++++++-
>  2 files changed, 38 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/torture/vect-absu-1.C
>
> diff --git a/gcc/testsuite/g++.dg/torture/vect-absu-1.C b/gcc/testsuite/g++.dg/torture/vect-absu-1.C
> new file mode 100644
> index 00000000000..0b2035f638f
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/torture/vect-absu-1.C
> @@ -0,0 +1,29 @@
> +// { dg-do run }
> +// PR middle-end/111285
> +
> +// The lowering of vect absu was done incorrectly
> +
> +#define vect1 __attribute__((vector_size(sizeof(int))))
> +
> +#define negabs(a) a < 0 ? a : -a
> +
> +__attribute__((noinline))
> +int s(int a)
> +{
> +  return negabs(a);
> +}
> +__attribute__((noinline))
> +vect1 int v(vect1 int a)
> +{
> +  return negabs(a);
> +}
> +
> +int main(void)
> +{
> +        for(int i = -10; i < 10; i++)
> +        {
> +          vect1 int t = {i};
> +          if (v(t)[0] != s(i))
> +            __builtin_abort();
> +        }
> +}
> diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
> index ef7d2dd259d..21d906e9c55 100644
> --- a/gcc/tree-vect-generic.cc
> +++ b/gcc/tree-vect-generic.cc
> @@ -168,7 +168,15 @@ do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
>          tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
>          enum tree_code code, tree type ATTRIBUTE_UNUSED)
>  {
> -  a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
> +  tree rhs_type = inner_type;
> +
> +  /* For ABSU_EXPR, use the signed type for the rhs if the rhs was signed. */
> +  if (code == ABSU_EXPR
> +      && ANY_INTEGRAL_TYPE_P (TREE_TYPE (a))
> +      && !TYPE_UNSIGNED (TREE_TYPE (a)))
> +    rhs_type = signed_type_for (rhs_type);
> +
> +  a = tree_vec_extract (gsi, rhs_type, a, bitsize, bitpos);
>    return gimplify_build1 (gsi, code, inner_type, a);
>  }
>
> --
> 2.43.0
>
diff mbox series

Patch

diff --git a/gcc/testsuite/g++.dg/torture/vect-absu-1.C b/gcc/testsuite/g++.dg/torture/vect-absu-1.C
new file mode 100644
index 00000000000..0b2035f638f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vect-absu-1.C
@@ -0,0 +1,29 @@ 
+// { dg-do run }
+// PR middle-end/111285
+
+// The lowering of vect absu was done incorrectly
+
+#define vect1 __attribute__((vector_size(sizeof(int))))
+
+#define negabs(a) a < 0 ? a : -a
+
+__attribute__((noinline))
+int s(int a)
+{
+  return negabs(a);
+}
+__attribute__((noinline))
+vect1 int v(vect1 int a)
+{
+  return negabs(a);
+}
+
+int main(void)
+{
+        for(int i = -10; i < 10; i++)
+        {
+          vect1 int t = {i};
+          if (v(t)[0] != s(i))
+            __builtin_abort();
+        }
+}
diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
index ef7d2dd259d..21d906e9c55 100644
--- a/gcc/tree-vect-generic.cc
+++ b/gcc/tree-vect-generic.cc
@@ -168,7 +168,15 @@  do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
 	 tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
 	 enum tree_code code, tree type ATTRIBUTE_UNUSED)
 {
-  a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
+  tree rhs_type = inner_type;
+
+  /* For ABSU_EXPR, use the signed type for the rhs if the rhs was signed. */
+  if (code == ABSU_EXPR
+      && ANY_INTEGRAL_TYPE_P (TREE_TYPE (a))
+      && !TYPE_UNSIGNED (TREE_TYPE (a)))
+    rhs_type = signed_type_for (rhs_type);
+
+  a = tree_vec_extract (gsi, rhs_type, a, bitsize, bitpos);
   return gimplify_build1 (gsi, code, inner_type, a);
 }