public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do
@ 2021-12-03  3:48 Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2021-12-03  3:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:6d6cbe57a5d147a1328b32fb2528846e733c5c3d

commit 6d6cbe57a5d147a1328b32fb2528846e733c5c3d
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 2 23:43:47 2021 -0300

    [PR103149] harden conditionals detach through mem if general regs won't do

Diff:
---
 gcc/gimple-harden-conditionals.cc           | 19 ++++++++++--
 gcc/testsuite/gcc.target/aarch64/pr103149.c | 13 ++++++++
 gcc/testsuite/gcc.target/riscv/pr103302.c   | 47 +++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..2c4796f5227 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
+#include "target.h"
+#include "rtl.h"
 #include "tree.h"
 #include "fold-const.h"
 #include "gimple.h"
@@ -132,13 +134,26 @@ detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
   tree ret = make_ssa_name (TREE_TYPE (val));
   SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
 
-  /* Output asm ("" : "=g" (ret) : "0" (val));  */
+  bool need_memory = true;
+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+  if (mode != BLKmode)
+    for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+      if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+	  && targetm.hard_regno_mode_ok (i, mode))
+	{
+	  need_memory = false;
+	  break;
+	}
+
+  const char *constraint = need_memory ? "=m" : "=g";
+
+  /* Output asm ("" : "=[gm]" (ret) : "0" (val));  */
   vec<tree, va_gc> *inputs = NULL;
   vec<tree, va_gc> *outputs = NULL;
   vec_safe_push (outputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (2, "=g")),
+		  (NULL_TREE, build_string (2, constraint)),
 		  ret));
   vec_safe_push (inputs,
 		 build_tree_list
diff --git a/gcc/testsuite/gcc.target/aarch64/pr103149.c b/gcc/testsuite/gcc.target/aarch64/pr103149.c
new file mode 100644
index 00000000000..e7283b4f569
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr103149.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+sve -O2 -fharden-conditional-branches -fno-tree-scev-cprop" } */
+
+/* -fharden-conditional-branches relies on ASMNESIA, that used to require
+   GENERAL_REGS even for vectorized booleans, which can't go on
+   GENERAL_REGS.  */
+
+void
+foo (int *p)
+{
+  while (*p < 1)
+    ++*p;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr103302.c b/gcc/testsuite/gcc.target/riscv/pr103302.c
new file mode 100644
index 00000000000..822c4087416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr103302.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-Og -fharden-compares -fno-tree-dce -fno-tree-fre " } */
+
+typedef unsigned char u8;
+typedef unsigned char __attribute__((__vector_size__ (32))) v256u8;
+typedef unsigned short __attribute__((__vector_size__ (32))) v256u16;
+typedef unsigned short __attribute__((__vector_size__ (64))) v512u16;
+typedef unsigned int u32;
+typedef unsigned int __attribute__((__vector_size__ (4))) v512u32;
+typedef unsigned long long __attribute__((__vector_size__ (32))) v256u64;
+typedef unsigned long long __attribute__((__vector_size__ (64))) v512u64;
+typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
+typedef unsigned __int128 __attribute__((__vector_size__ (64))) v512u128;
+
+v512u16 g;
+
+void
+foo0 (u8 u8_0, v256u16 v256u16_0, v512u16 v512u16_0, u32 u32_0, v512u32,
+      v256u64 v256u64_0, v512u64 v512u64_0, v256u128 v256u128_0,
+      v512u128 v512u128_0)
+{
+  u32_0 <= (v512u128) (v512u128_0 != u8_0);
+  v512u64 v512u64_1 =
+    __builtin_shufflevector (v256u64_0, v512u64_0, 7, 8, 0, 9, 5, 0, 3, 1);
+  g = v512u16_0;
+  (v256u8) v256u16_0 + (v256u8) v256u128_0;
+}
+
+int
+main (void)
+{
+  foo0 (40, (v256u16)
+	{
+	}, (v512u16)
+	{
+	}, 0, (v512u32)
+	{
+	}, (v256u64)
+	{
+	}, (v512u64)
+	{
+	}, (v256u128)
+	{
+	}, (v512u128)
+	{
+	});
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do
@ 2021-12-03  6:29 Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2021-12-03  6:29 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:372b210a08d1dab4b530d2f6b7be469e8132c497

commit 372b210a08d1dab4b530d2f6b7be469e8132c497
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 2 23:43:47 2021 -0300

    [PR103149] harden conditionals detach through mem if general regs won't do

Diff:
---
 gcc/gimple-harden-conditionals.cc           | 67 ++++++++++++++++++++++++++---
 gcc/testsuite/gcc.target/aarch64/pr103149.c | 13 ++++++
 gcc/testsuite/gcc.target/riscv/pr103302.c   | 47 ++++++++++++++++++++
 3 files changed, 121 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..81867d6e427 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
+#include "target.h"
+#include "rtl.h"
 #include "tree.h"
 #include "fold-const.h"
 #include "gimple.h"
@@ -132,25 +134,78 @@ detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
   tree ret = make_ssa_name (TREE_TYPE (val));
   SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
 
-  /* Output asm ("" : "=g" (ret) : "0" (val));  */
+  /* Some modes won't fit in general regs, so we fall back to memory
+     for them.  ??? It would be ideal to try to identify an alternate,
+     wider or more suitable register class, and use the corresponding
+     constraint, but there's no logic to go from register class to
+     constraint, even if there is a corresponding constraint, and even
+     if we could enumerate constraints, we can't get to their string
+     either.  So this will do for now.  */
+  bool need_memory = true;
+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+  if (mode != BLKmode)
+    for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+      if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+	  && targetm.hard_regno_mode_ok (i, mode))
+	{
+	  need_memory = false;
+	  break;
+	}
+
+  tree asminput = val;
+  tree asmoutput = ret;
+  const char *constraint_out = need_memory ? "=m" : "=g";
+  const char *constraint_in = need_memory ? "m" : "0";
+
+  if (need_memory)
+    {
+      tree temp = create_tmp_var (TREE_TYPE (val), "dtch");
+      mark_addressable (temp);
+
+      gassign *copyin = gimple_build_assign (temp, asminput);
+      gimple_set_location (copyin, loc);
+      gsi_insert_before (gsip, copyin, GSI_SAME_STMT);
+
+      asminput = asmoutput = temp;
+    }
+
+  /* Output an asm statement with matching input and output.  It does
+     nothing, but after it the compiler no longer knows the output
+     still holds the same value as the input.  */
   vec<tree, va_gc> *inputs = NULL;
   vec<tree, va_gc> *outputs = NULL;
   vec_safe_push (outputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (2, "=g")),
-		  ret));
+		  (NULL_TREE, build_string (strlen (constraint_out),
+					    constraint_out)),
+		  asmoutput));
   vec_safe_push (inputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (1, "0")),
-		  val));
+		  (NULL_TREE, build_string (strlen (constraint_in),
+					    constraint_in)),
+		  asminput));
   gasm *detach = gimple_build_asm_vec ("", inputs, outputs,
 				       NULL, NULL);
   gimple_set_location (detach, loc);
   gsi_insert_before (gsip, detach, GSI_SAME_STMT);
 
-  SSA_NAME_DEF_STMT (ret) = detach;
+  if (need_memory)
+    {
+      gassign *copyout = gimple_build_assign (ret, asmoutput);
+      gimple_set_location (copyout, loc);
+      gsi_insert_before (gsip, copyout, GSI_SAME_STMT);
+      SSA_NAME_DEF_STMT (ret) = copyout;
+
+      gassign *clobber = gimple_build_assign (asmoutput,
+					      build_clobber
+					      (TREE_TYPE (asmoutput)));
+      gimple_set_location (clobber, loc);
+      gsi_insert_before (gsip, clobber, GSI_SAME_STMT);
+    }
+  else
+    SSA_NAME_DEF_STMT (ret) = detach;
 
   return ret;
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/pr103149.c b/gcc/testsuite/gcc.target/aarch64/pr103149.c
new file mode 100644
index 00000000000..e7283b4f569
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr103149.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+sve -O2 -fharden-conditional-branches -fno-tree-scev-cprop" } */
+
+/* -fharden-conditional-branches relies on ASMNESIA, that used to require
+   GENERAL_REGS even for vectorized booleans, which can't go on
+   GENERAL_REGS.  */
+
+void
+foo (int *p)
+{
+  while (*p < 1)
+    ++*p;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr103302.c b/gcc/testsuite/gcc.target/riscv/pr103302.c
new file mode 100644
index 00000000000..822c4087416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr103302.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-Og -fharden-compares -fno-tree-dce -fno-tree-fre " } */
+
+typedef unsigned char u8;
+typedef unsigned char __attribute__((__vector_size__ (32))) v256u8;
+typedef unsigned short __attribute__((__vector_size__ (32))) v256u16;
+typedef unsigned short __attribute__((__vector_size__ (64))) v512u16;
+typedef unsigned int u32;
+typedef unsigned int __attribute__((__vector_size__ (4))) v512u32;
+typedef unsigned long long __attribute__((__vector_size__ (32))) v256u64;
+typedef unsigned long long __attribute__((__vector_size__ (64))) v512u64;
+typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
+typedef unsigned __int128 __attribute__((__vector_size__ (64))) v512u128;
+
+v512u16 g;
+
+void
+foo0 (u8 u8_0, v256u16 v256u16_0, v512u16 v512u16_0, u32 u32_0, v512u32,
+      v256u64 v256u64_0, v512u64 v512u64_0, v256u128 v256u128_0,
+      v512u128 v512u128_0)
+{
+  u32_0 <= (v512u128) (v512u128_0 != u8_0);
+  v512u64 v512u64_1 =
+    __builtin_shufflevector (v256u64_0, v512u64_0, 7, 8, 0, 9, 5, 0, 3, 1);
+  g = v512u16_0;
+  (v256u8) v256u16_0 + (v256u8) v256u128_0;
+}
+
+int
+main (void)
+{
+  foo0 (40, (v256u16)
+	{
+	}, (v512u16)
+	{
+	}, 0, (v512u32)
+	{
+	}, (v256u64)
+	{
+	}, (v512u64)
+	{
+	}, (v256u128)
+	{
+	}, (v512u128)
+	{
+	});
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do
@ 2021-12-03  6:17 Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2021-12-03  6:17 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f2404662495b1e69f46dfe7acee7fe048a29f64b

commit f2404662495b1e69f46dfe7acee7fe048a29f64b
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 2 23:43:47 2021 -0300

    [PR103149] harden conditionals detach through mem if general regs won't do

Diff:
---
 gcc/gimple-harden-conditionals.cc           | 61 ++++++++++++++++++++++++++---
 gcc/testsuite/gcc.target/aarch64/pr103149.c | 13 ++++++
 gcc/testsuite/gcc.target/riscv/pr103302.c   | 47 ++++++++++++++++++++++
 3 files changed, 115 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..1fca6bcb2e2 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
+#include "target.h"
+#include "rtl.h"
 #include "tree.h"
 #include "fold-const.h"
 #include "gimple.h"
@@ -132,25 +134,72 @@ detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
   tree ret = make_ssa_name (TREE_TYPE (val));
   SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
 
-  /* Output asm ("" : "=g" (ret) : "0" (val));  */
+  /* Some modes won't fit in general regs, so we fall back to memory
+     for them.  ??? It would be ideal to try to identify an alternate,
+     wider or more suitable register class, and use the corresponding
+     constraint, but there's no logic to go from register class to
+     constraint, even if there is a corresponding constraint, and even
+     if we could enumerate constraints, we can't get to their string
+     either.  So this will do for now.  */
+  bool need_memory = true;
+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+  if (mode != BLKmode)
+    for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+      if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+	  && targetm.hard_regno_mode_ok (i, mode))
+	{
+	  need_memory = false;
+	  break;
+	}
+
+  tree asminput = val;
+  tree asmoutput = ret;
+  const char *constraint_out = need_memory ? "=m" : "=g";
+  const char *constraint_in = need_memory ? "m" : "0";
+
+  if (need_memory)
+    {
+      tree temp = create_tmp_var (TREE_TYPE (val), "dtch");
+      mark_addressable (temp);
+
+      gassign *copyin = gimple_build_assign (temp, asminput);
+      gimple_set_location (copyin, loc);
+      gsi_insert_before (gsip, copyin, GSI_SAME_STMT);
+
+      asminput = asmoutput = temp;
+    }
+
+  /* Output an asm statement with matching input and output.  It does
+     nothing, but after it the compiler no longer knows the output
+     still holds the same value as the input.  */
   vec<tree, va_gc> *inputs = NULL;
   vec<tree, va_gc> *outputs = NULL;
   vec_safe_push (outputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (2, "=g")),
-		  ret));
+		  (NULL_TREE, build_string (strlen (constraint_out),
+					    constraint_out)),
+		  asmoutput));
   vec_safe_push (inputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (1, "0")),
-		  val));
+		  (NULL_TREE, build_string (strlen (constraint_in),
+					    constraint_in)),
+		  asminput));
   gasm *detach = gimple_build_asm_vec ("", inputs, outputs,
 				       NULL, NULL);
   gimple_set_location (detach, loc);
   gsi_insert_before (gsip, detach, GSI_SAME_STMT);
 
-  SSA_NAME_DEF_STMT (ret) = detach;
+  if (need_memory)
+    {
+      gassign *copyout = gimple_build_assign (ret, asmoutput);
+      gimple_set_location (copyout, loc);
+      gsi_insert_before (gsip, copyout, GSI_SAME_STMT);
+      SSA_NAME_DEF_STMT (ret) = copyout;
+    }
+  else
+    SSA_NAME_DEF_STMT (ret) = detach;
 
   return ret;
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/pr103149.c b/gcc/testsuite/gcc.target/aarch64/pr103149.c
new file mode 100644
index 00000000000..e7283b4f569
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr103149.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+sve -O2 -fharden-conditional-branches -fno-tree-scev-cprop" } */
+
+/* -fharden-conditional-branches relies on ASMNESIA, that used to require
+   GENERAL_REGS even for vectorized booleans, which can't go on
+   GENERAL_REGS.  */
+
+void
+foo (int *p)
+{
+  while (*p < 1)
+    ++*p;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr103302.c b/gcc/testsuite/gcc.target/riscv/pr103302.c
new file mode 100644
index 00000000000..822c4087416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr103302.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-Og -fharden-compares -fno-tree-dce -fno-tree-fre " } */
+
+typedef unsigned char u8;
+typedef unsigned char __attribute__((__vector_size__ (32))) v256u8;
+typedef unsigned short __attribute__((__vector_size__ (32))) v256u16;
+typedef unsigned short __attribute__((__vector_size__ (64))) v512u16;
+typedef unsigned int u32;
+typedef unsigned int __attribute__((__vector_size__ (4))) v512u32;
+typedef unsigned long long __attribute__((__vector_size__ (32))) v256u64;
+typedef unsigned long long __attribute__((__vector_size__ (64))) v512u64;
+typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
+typedef unsigned __int128 __attribute__((__vector_size__ (64))) v512u128;
+
+v512u16 g;
+
+void
+foo0 (u8 u8_0, v256u16 v256u16_0, v512u16 v512u16_0, u32 u32_0, v512u32,
+      v256u64 v256u64_0, v512u64 v512u64_0, v256u128 v256u128_0,
+      v512u128 v512u128_0)
+{
+  u32_0 <= (v512u128) (v512u128_0 != u8_0);
+  v512u64 v512u64_1 =
+    __builtin_shufflevector (v256u64_0, v512u64_0, 7, 8, 0, 9, 5, 0, 3, 1);
+  g = v512u16_0;
+  (v256u8) v256u16_0 + (v256u8) v256u128_0;
+}
+
+int
+main (void)
+{
+  foo0 (40, (v256u16)
+	{
+	}, (v512u16)
+	{
+	}, 0, (v512u32)
+	{
+	}, (v256u64)
+	{
+	}, (v512u64)
+	{
+	}, (v256u128)
+	{
+	}, (v512u128)
+	{
+	});
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do
@ 2021-12-03  3:11 Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2021-12-03  3:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7526057fabd3395f1985f3016d7bb7d02200fb3e

commit 7526057fabd3395f1985f3016d7bb7d02200fb3e
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Dec 2 23:43:47 2021 -0300

    [PR103149] harden conditionals detach through mem if general regs won't do

Diff:
---
 gcc/gimple-harden-conditionals.cc           | 17 +++++++++--
 gcc/testsuite/gcc.target/aarch64/pr103149.c | 13 ++++++++
 gcc/testsuite/gcc.target/riscv/pr103302.c   | 47 +++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..2ebd2ff4387 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -132,13 +132,26 @@ detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
   tree ret = make_ssa_name (TREE_TYPE (val));
   SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
 
-  /* Output asm ("" : "=g" (ret) : "0" (val));  */
+  bool need_memory = true;
+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+  if (mode != BLKmode)
+    for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+      if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+	  && targetm.hard_regno_mode_ok (i, mode))
+	{
+	  need_memory = false;
+	  break;
+	}
+
+  const char *constraint = need_memory ? "=m" : "=g";
+
+  /* Output asm ("" : "=[gm]" (ret) : "0" (val));  */
   vec<tree, va_gc> *inputs = NULL;
   vec<tree, va_gc> *outputs = NULL;
   vec_safe_push (outputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (2, "=g")),
+		  (NULL_TREE, build_string (2, constraint)),
 		  ret));
   vec_safe_push (inputs,
 		 build_tree_list
diff --git a/gcc/testsuite/gcc.target/aarch64/pr103149.c b/gcc/testsuite/gcc.target/aarch64/pr103149.c
new file mode 100644
index 00000000000..e7283b4f569
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr103149.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+sve -O2 -fharden-conditional-branches -fno-tree-scev-cprop" } */
+
+/* -fharden-conditional-branches relies on ASMNESIA, that used to require
+   GENERAL_REGS even for vectorized booleans, which can't go on
+   GENERAL_REGS.  */
+
+void
+foo (int *p)
+{
+  while (*p < 1)
+    ++*p;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr103302.c b/gcc/testsuite/gcc.target/riscv/pr103302.c
new file mode 100644
index 00000000000..822c4087416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr103302.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-Og -fharden-compares -fno-tree-dce -fno-tree-fre " } */
+
+typedef unsigned char u8;
+typedef unsigned char __attribute__((__vector_size__ (32))) v256u8;
+typedef unsigned short __attribute__((__vector_size__ (32))) v256u16;
+typedef unsigned short __attribute__((__vector_size__ (64))) v512u16;
+typedef unsigned int u32;
+typedef unsigned int __attribute__((__vector_size__ (4))) v512u32;
+typedef unsigned long long __attribute__((__vector_size__ (32))) v256u64;
+typedef unsigned long long __attribute__((__vector_size__ (64))) v512u64;
+typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
+typedef unsigned __int128 __attribute__((__vector_size__ (64))) v512u128;
+
+v512u16 g;
+
+void
+foo0 (u8 u8_0, v256u16 v256u16_0, v512u16 v512u16_0, u32 u32_0, v512u32,
+      v256u64 v256u64_0, v512u64 v512u64_0, v256u128 v256u128_0,
+      v512u128 v512u128_0)
+{
+  u32_0 <= (v512u128) (v512u128_0 != u8_0);
+  v512u64 v512u64_1 =
+    __builtin_shufflevector (v256u64_0, v512u64_0, 7, 8, 0, 9, 5, 0, 3, 1);
+  g = v512u16_0;
+  (v256u8) v256u16_0 + (v256u8) v256u128_0;
+}
+
+int
+main (void)
+{
+  foo0 (40, (v256u16)
+	{
+	}, (v512u16)
+	{
+	}, 0, (v512u32)
+	{
+	}, (v256u64)
+	{
+	}, (v512u64)
+	{
+	}, (v256u128)
+	{
+	}, (v512u128)
+	{
+	});
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do
@ 2021-12-03  2:56 Alexandre Oliva
  0 siblings, 0 replies; 5+ messages in thread
From: Alexandre Oliva @ 2021-12-03  2:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a1b9e323d4112ef8155c313965e551303fede548

commit a1b9e323d4112ef8155c313965e551303fede548
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Thu Dec 2 23:43:47 2021 -0300

    [PR103149] harden conditionals detach through mem if general regs won't do

Diff:
---
 gcc/gimple-harden-conditionals.cc           | 28 ++++++++++++++---
 gcc/testsuite/gcc.target/aarch64/pr103149.c | 13 ++++++++
 gcc/testsuite/gcc.target/riscv/pr103302.c   | 47 +++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..d07475676c0 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -132,19 +132,39 @@ detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
   tree ret = make_ssa_name (TREE_TYPE (val));
   SET_SSA_NAME_VAR_OR_IDENTIFIER (ret, SSA_NAME_IDENTIFIER (val));
 
-  /* Output asm ("" : "=g" (ret) : "0" (val));  */
+  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
+  bool need_memory = true;
+  if (mode != BLKmode)
+    {
+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+	if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
+	    && targetm.hard_regno_mode_ok (i, mode))
+	  {
+	    need_memory = false;
+	    break;
+	  }
+    }
+
+  tree input = val;
+  tree output = ret;
+  const char *constraint = "=g";
+
+  if (need_memory)
+    constraint = "=m";
+
+  /* Output asm ("" : "=[gm]" (ret) : "0" (val));  */
   vec<tree, va_gc> *inputs = NULL;
   vec<tree, va_gc> *outputs = NULL;
   vec_safe_push (outputs,
 		 build_tree_list
 		 (build_tree_list
-		  (NULL_TREE, build_string (2, "=g")),
-		  ret));
+		  (NULL_TREE, build_string (2, constraint)),
+		  output));
   vec_safe_push (inputs,
 		 build_tree_list
 		 (build_tree_list
 		  (NULL_TREE, build_string (1, "0")),
-		  val));
+		  input));
   gasm *detach = gimple_build_asm_vec ("", inputs, outputs,
 				       NULL, NULL);
   gimple_set_location (detach, loc);
diff --git a/gcc/testsuite/gcc.target/aarch64/pr103149.c b/gcc/testsuite/gcc.target/aarch64/pr103149.c
new file mode 100644
index 00000000000..e7283b4f569
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr103149.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+sve -O2 -fharden-conditional-branches -fno-tree-scev-cprop" } */
+
+/* -fharden-conditional-branches relies on ASMNESIA, that used to require
+   GENERAL_REGS even for vectorized booleans, which can't go on
+   GENERAL_REGS.  */
+
+void
+foo (int *p)
+{
+  while (*p < 1)
+    ++*p;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr103302.c b/gcc/testsuite/gcc.target/riscv/pr103302.c
new file mode 100644
index 00000000000..822c4087416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr103302.c
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-Og -fharden-compares -fno-tree-dce -fno-tree-fre " } */
+
+typedef unsigned char u8;
+typedef unsigned char __attribute__((__vector_size__ (32))) v256u8;
+typedef unsigned short __attribute__((__vector_size__ (32))) v256u16;
+typedef unsigned short __attribute__((__vector_size__ (64))) v512u16;
+typedef unsigned int u32;
+typedef unsigned int __attribute__((__vector_size__ (4))) v512u32;
+typedef unsigned long long __attribute__((__vector_size__ (32))) v256u64;
+typedef unsigned long long __attribute__((__vector_size__ (64))) v512u64;
+typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
+typedef unsigned __int128 __attribute__((__vector_size__ (64))) v512u128;
+
+v512u16 g;
+
+void
+foo0 (u8 u8_0, v256u16 v256u16_0, v512u16 v512u16_0, u32 u32_0, v512u32,
+      v256u64 v256u64_0, v512u64 v512u64_0, v256u128 v256u128_0,
+      v512u128 v512u128_0)
+{
+  u32_0 <= (v512u128) (v512u128_0 != u8_0);
+  v512u64 v512u64_1 =
+    __builtin_shufflevector (v256u64_0, v512u64_0, 7, 8, 0, 9, 5, 0, 3, 1);
+  g = v512u16_0;
+  (v256u8) v256u16_0 + (v256u8) v256u128_0;
+}
+
+int
+main (void)
+{
+  foo0 (40, (v256u16)
+	{
+	}, (v512u16)
+	{
+	}, 0, (v512u32)
+	{
+	}, (v256u64)
+	{
+	}, (v512u64)
+	{
+	}, (v256u128)
+	{
+	}, (v512u128)
+	{
+	});
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-12-03  6:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03  3:48 [gcc(refs/users/aoliva/heads/testme)] [PR103149] harden conditionals detach through mem if general regs won't do Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2021-12-03  6:29 Alexandre Oliva
2021-12-03  6:17 Alexandre Oliva
2021-12-03  3:11 Alexandre Oliva
2021-12-03  2:56 Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).