From: Marek Polacek Date: Tue, 4 Nov 2014 09:30:47 +0000 (+0000) Subject: ubsan.c (instrument_object_size): Optimize [x & CST] array accesses. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74e3d997b38dcecab32c463edbdb8a494ac2e7f3;p=gcc.git ubsan.c (instrument_object_size): Optimize [x & CST] array accesses. * ubsan.c (instrument_object_size): Optimize [x & CST] array accesses. testsuite/ * c-c++-common/ubsan/object-size-10.c: New test. From-SVN: r217071 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73b8e867aa1..d5a2370da72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2014-11-04 Marek Polacek + + * ubsan.c (instrument_object_size): Optimize [x & CST] array accesses. + 2014-11-03 Jan-Benedict Glaw * config/rx/rx.c (rx_handle_func_attribute): Mark unused argument. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5c16ebee6a8..fc531042a6f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-11-04 Marek Polacek + + * c-c++-common/ubsan/object-size-10.c: New test. + 2014-11-03 Dominik Vogt * build-go/gcc/testsuite/gcc/godump-1.out: Update godump tests. diff --git a/gcc/testsuite/c-c++-common/ubsan/object-size-10.c b/gcc/testsuite/c-c++-common/ubsan/object-size-10.c new file mode 100644 index 00000000000..ebc8582ec3c --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/object-size-10.c @@ -0,0 +1,79 @@ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-fsanitize=undefined" } */ + +static char a[128]; +static int b[128]; + +__attribute__ ((noinline, noclone)) int +fn1 (int i) +{ + asm (""); + return a[i & 127]; +} + +__attribute__ ((noinline, noclone)) int +fn2 (int i) +{ + asm (""); + return a[i & 128]; +} + +/* { dg-output "index 128 out of bounds for type 'char \\\[128\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ + +__attribute__ ((noinline, noclone)) int +fn3 (int i) +{ + asm (""); + return b[i & 127]; +} + +__attribute__ ((noinline, noclone)) int +fn4 (int i) +{ + asm (""); + return b[i & 128]; +} + +/* { dg-output "\[^\n\r]*index 128 out of bounds for type 'int \\\[128\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ + +__attribute__ ((noinline, noclone)) int +fn5 (int i, int j) +{ + asm (""); + return b[i & j]; +} + +/* { dg-output "\[^\n\r]*index 128 out of bounds for type 'int \\\[128\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ + +__attribute__ ((noinline, noclone)) int +fn6 (int i) +{ + asm (""); + return b[i & 0]; +} + +int +main (void) +{ + fn1 (128); + fn2 (128); + fn3 (128); + fn4 (128); + fn5 (128, 127); + fn5 (128, 128); + fn6 (128); + return 0; +} diff --git a/gcc/ubsan.c b/gcc/ubsan.c index ed2fc542fe5..41cf546cde3 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -1438,6 +1438,7 @@ instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs) location_t loc = gimple_location (stmt); tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt); tree type; + tree index = NULL_TREE; HOST_WIDE_INT size_in_bytes; type = TREE_TYPE (t); @@ -1456,6 +1457,8 @@ instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs) } break; case ARRAY_REF: + index = TREE_OPERAND (t, 1); + break; case INDIRECT_REF: case MEM_REF: case VAR_DECL: @@ -1537,6 +1540,24 @@ instrument_object_size (gimple_stmt_iterator *gsi, bool is_lhs) && tree_int_cst_le (t, sizet)) return; + if (index != NULL_TREE + && TREE_CODE (index) == SSA_NAME + && TREE_CODE (sizet) == INTEGER_CST) + { + gimple def = SSA_NAME_DEF_STMT (index); + if (is_gimple_assign (def) + && gimple_assign_rhs_code (def) == BIT_AND_EXPR + && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST) + { + tree cst = gimple_assign_rhs2 (def); + tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet, + TYPE_SIZE_UNIT (type)); + if (tree_int_cst_sgn (cst) >= 0 + && tree_int_cst_lt (cst, sz)) + return; + } + } + /* Nope. Emit the check. */ t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);