Hi,
The patch below attempts to fix the PR. I checked that it did not
break any of mpx.exp tests, but I did not run the full testing yet.
Would like to know whether this approach is generally correct or not.
The issue is that we have the hard reg vector variable:
typedef int U __attribute__ ((vector_size (16)));
register U u asm("xmm0");
and chkp tries to instrument access to it:
return u[i];
by doing that:
__bound_tmp.0_4 = __builtin_ia32_bndmk (&u, 16);
However, you cannot take an address of a register variable (in fact if
you do that, the compiler will give you "address of register variable
āuā requested" error), so expand, sensibly, gives an ICE on on &u
here. I believe that if there is no pointers, pointer bounds checker
shouldn't get involved into that business. What do you think?
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 75caf83..e39ec9a 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -3383,6 +3383,7 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
tree comp_to_narrow = NULL_TREE;
tree last_comp = NULL_TREE;
bool array_ref_found = false;
+ bool is_register_var = false;
tree *nodes;
tree var;
int len;
@@ -3440,6 +3441,9 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|| TREE_CODE (var) == STRING_CST
|| TREE_CODE (var) == SSA_NAME);
+ if (VAR_P (var) && DECL_HARD_REGISTER (var))
+ is_register_var = true;
+
*ptr = chkp_build_addr_expr (var);
}
@@ -3455,7 +3459,11 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
if (TREE_CODE (var) == ARRAY_REF)
{
- *safe = false;
+ // Mark it as unsafe, unless the array being accessed
+ // has been explicitly placed on a register: in this
+ // case we cannot take a pointer of this variable,
+ // so we don't instrument the access.
+ *safe = is_register_var;
array_ref_found = true;
if (flag_chkp_narrow_bounds
&& !flag_chkp_narrow_to_innermost_arrray
@@ -4001,6 +4009,19 @@ chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
bool bitfield;
tree elt;
+ {
+ // We don't instrument accesses to arrays that
+ // are explicitely assigned to hard registers.
+ HOST_WIDE_INT bitsize, bitpos;
+ tree base, offset;
+ machine_mode mode;
+ int unsignedp, reversep, volatilep = 0;
+ base = get_inner_reference (node, &bitsize, &bitpos, &offset, &mode,
+ &unsignedp, &reversep, &volatilep);
+ if (VAR_P (base) && DECL_HARD_REGISTER (base))
+ safe = true;
+ }
+
if (safe)
{
/* We are not going to generate any checks, so do not
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr79990.c
b/gcc/testsuite/gcc.target/i386/mpx/pr79990.c
new file mode 100644
index 0000000..a27734d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr79990.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+typedef int U __attribute__ ((vector_size (16)));
+
+int
+foo (int i)
+{
+#if __SSE2__
+ register
+#endif
+ U u
+#if __SSE2__
+ asm ("xmm0")
+#endif
+ ;
+ return u[i];
+}
regards,
Alexander