Message ID | 20170901111654.GE2323@tucnak |
---|---|
State | New |
Headers | show |
Series | Add UBSAN_{PTR,BOUNDS} folding (PR sanitizer/81981) | expand |
On September 1, 2017 1:16:54 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote: >Hi! > >This patch fixes the following testcase by folding some ubsan internal >fns >we'd either remove anyway during sanopt, or lower into if (cond) >do_something during sanopt where cond would be always false. > >Additionally, I've tried to clean up a little bit IFN_UBSAN_OBJECT_SIZE >handling by using variables for the call arguments that make it clear >what the arguments are. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? I think there's a helper for replace - with-nop. Richard. >2017-09-01 Jakub Jelinek <jakub@redhat.com> > > PR sanitizer/81981 > * gimple-fold.c (gimple_fold_call): Optimize away useless UBSAN_PTR > and UBSAN_BOUNDS internal calls. Clean up IFN_UBSAN_OBJECT_SIZE > handling. > > * gcc.dg/ubsan/pr81981.c: New test. > >--- gcc/gimple-fold.c.jj 2017-08-10 02:31:21.000000000 +0200 >+++ gcc/gimple-fold.c 2017-08-29 18:50:49.993673432 +0200 >@@ -3938,11 +3938,23 @@ gimple_fold_call (gimple_stmt_iterator * > gimple_call_arg (stmt, 2)); > break; > case IFN_UBSAN_OBJECT_SIZE: >- if (integer_all_onesp (gimple_call_arg (stmt, 2)) >- || (TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST >- && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST >- && tree_int_cst_le (gimple_call_arg (stmt, 1), >- gimple_call_arg (stmt, 2)))) >+ { >+ tree offset = gimple_call_arg (stmt, 1); >+ tree objsize = gimple_call_arg (stmt, 2); >+ if (integer_all_onesp (objsize) >+ || (TREE_CODE (offset) == INTEGER_CST >+ && TREE_CODE (objsize) == INTEGER_CST >+ && tree_int_cst_le (offset, objsize))) >+ { >+ gsi_replace (gsi, gimple_build_nop (), false); >+ unlink_stmt_vdef (stmt); >+ release_defs (stmt); >+ return true; >+ } >+ } >+ break; >+ case IFN_UBSAN_PTR: >+ if (integer_zerop (gimple_call_arg (stmt, 1))) > { > gsi_replace (gsi, gimple_build_nop (), false); > unlink_stmt_vdef (stmt); >@@ -3950,6 +3962,25 @@ gimple_fold_call (gimple_stmt_iterator * > return true; > } > break; >+ case IFN_UBSAN_BOUNDS: >+ { >+ tree index = gimple_call_arg (stmt, 1); >+ tree bound = gimple_call_arg (stmt, 2); >+ if (TREE_CODE (index) == INTEGER_CST >+ && TREE_CODE (bound) == INTEGER_CST) >+ { >+ index = fold_convert (TREE_TYPE (bound), index); >+ if (TREE_CODE (index) == INTEGER_CST >+ && tree_int_cst_le (index, bound)) >+ { >+ gsi_replace (gsi, gimple_build_nop (), false); >+ unlink_stmt_vdef (stmt); >+ release_defs (stmt); >+ return true; >+ } >+ } >+ } >+ break; > case IFN_GOACC_DIM_SIZE: > case IFN_GOACC_DIM_POS: > result = fold_internal_goacc_dim (stmt); >--- gcc/testsuite/gcc.dg/ubsan/pr81981.c.jj 2017-08-29 >18:54:33.826107761 +0200 >+++ gcc/testsuite/gcc.dg/ubsan/pr81981.c 2017-08-29 18:55:36.721386827 >+0200 >@@ -0,0 +1,21 @@ >+/* PR sanitizer/81981 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined >-ffat-lto-objects" } */ >+ >+int v; >+ >+int >+foo (int i) >+{ >+ int t[1], u[1]; >+ int n = 0; >+ >+ if (i) >+ { >+ t[n] = i; >+ u[0] = i; >+ } >+ >+ v = u[0]; /* { dg-warning "may be used uninitialized in this >function" } */ >+ return t[0]; /* { dg-warning "may be used uninitialized in this >function" } */ >+} > > Jakub
On Fri, Sep 01, 2017 at 02:32:43PM +0200, Richard Biener wrote: > On September 1, 2017 1:16:54 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote: > >Hi! > > > >This patch fixes the following testcase by folding some ubsan internal > >fns > >we'd either remove anyway during sanopt, or lower into if (cond) > >do_something during sanopt where cond would be always false. > > > >Additionally, I've tried to clean up a little bit IFN_UBSAN_OBJECT_SIZE > >handling by using variables for the call arguments that make it clear > >what the arguments are. > > > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > I think there's a helper for replace - with-nop. Can't find it. gimplify_and_update_call_from_tree has to add it, but I'd need to call it with something that gimplifies into empty sequence (void_node?) and it would still go through push_gimplify_context/gimplify_and_add/pop_gimplify_context etc., which looks quite expensive. > >2017-09-01 Jakub Jelinek <jakub@redhat.com> > > > > PR sanitizer/81981 > > * gimple-fold.c (gimple_fold_call): Optimize away useless UBSAN_PTR > > and UBSAN_BOUNDS internal calls. Clean up IFN_UBSAN_OBJECT_SIZE > > handling. > > > > * gcc.dg/ubsan/pr81981.c: New test. > > > >--- gcc/gimple-fold.c.jj 2017-08-10 02:31:21.000000000 +0200 > >+++ gcc/gimple-fold.c 2017-08-29 18:50:49.993673432 +0200 > >@@ -3938,11 +3938,23 @@ gimple_fold_call (gimple_stmt_iterator * > > gimple_call_arg (stmt, 2)); > > break; > > case IFN_UBSAN_OBJECT_SIZE: > >- if (integer_all_onesp (gimple_call_arg (stmt, 2)) > >- || (TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST > >- && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST > >- && tree_int_cst_le (gimple_call_arg (stmt, 1), > >- gimple_call_arg (stmt, 2)))) > >+ { > >+ tree offset = gimple_call_arg (stmt, 1); > >+ tree objsize = gimple_call_arg (stmt, 2); > >+ if (integer_all_onesp (objsize) > >+ || (TREE_CODE (offset) == INTEGER_CST > >+ && TREE_CODE (objsize) == INTEGER_CST > >+ && tree_int_cst_le (offset, objsize))) > >+ { > >+ gsi_replace (gsi, gimple_build_nop (), false); > >+ unlink_stmt_vdef (stmt); > >+ release_defs (stmt); > >+ return true; > >+ } > >+ } > >+ break; > >+ case IFN_UBSAN_PTR: > >+ if (integer_zerop (gimple_call_arg (stmt, 1))) > > { > > gsi_replace (gsi, gimple_build_nop (), false); > > unlink_stmt_vdef (stmt); > >@@ -3950,6 +3962,25 @@ gimple_fold_call (gimple_stmt_iterator * > > return true; > > } > > break; > >+ case IFN_UBSAN_BOUNDS: > >+ { > >+ tree index = gimple_call_arg (stmt, 1); > >+ tree bound = gimple_call_arg (stmt, 2); > >+ if (TREE_CODE (index) == INTEGER_CST > >+ && TREE_CODE (bound) == INTEGER_CST) > >+ { > >+ index = fold_convert (TREE_TYPE (bound), index); > >+ if (TREE_CODE (index) == INTEGER_CST > >+ && tree_int_cst_le (index, bound)) > >+ { > >+ gsi_replace (gsi, gimple_build_nop (), false); > >+ unlink_stmt_vdef (stmt); > >+ release_defs (stmt); > >+ return true; > >+ } > >+ } > >+ } > >+ break; > > case IFN_GOACC_DIM_SIZE: > > case IFN_GOACC_DIM_POS: > > result = fold_internal_goacc_dim (stmt); > >--- gcc/testsuite/gcc.dg/ubsan/pr81981.c.jj 2017-08-29 > >18:54:33.826107761 +0200 > >+++ gcc/testsuite/gcc.dg/ubsan/pr81981.c 2017-08-29 18:55:36.721386827 > >+0200 > >@@ -0,0 +1,21 @@ > >+/* PR sanitizer/81981 */ > >+/* { dg-do compile } */ > >+/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined > >-ffat-lto-objects" } */ > >+ > >+int v; > >+ > >+int > >+foo (int i) > >+{ > >+ int t[1], u[1]; > >+ int n = 0; > >+ > >+ if (i) > >+ { > >+ t[n] = i; > >+ u[0] = i; > >+ } > >+ > >+ v = u[0]; /* { dg-warning "may be used uninitialized in this > >function" } */ > >+ return t[0]; /* { dg-warning "may be used uninitialized in this > >function" } */ > >+} > > > > Jakub Jakub
On September 1, 2017 3:53:28 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote: >On Fri, Sep 01, 2017 at 02:32:43PM +0200, Richard Biener wrote: >> On September 1, 2017 1:16:54 PM GMT+02:00, Jakub Jelinek ><jakub@redhat.com> wrote: >> >Hi! >> > >> >This patch fixes the following testcase by folding some ubsan >internal >> >fns >> >we'd either remove anyway during sanopt, or lower into if (cond) >> >do_something during sanopt where cond would be always false. >> > >> >Additionally, I've tried to clean up a little bit >IFN_UBSAN_OBJECT_SIZE >> >handling by using variables for the call arguments that make it >clear >> >what the arguments are. >> > >> >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? >> >> I think there's a helper for replace - with-nop. > >Can't find it. >gimplify_and_update_call_from_tree has to add it, but I'd need >to call it with something that gimplifies into empty sequence >(void_node?) >and it would still go through >push_gimplify_context/gimplify_and_add/pop_gimplify_context >etc., which looks quite expensive. OK, I thought we have one. Can you add a helper for it please? replace_with_nop or so? I thought there's maybe replace_with_value which handles null lhs by replacing with nop. (can't check, writing from phone) Richard. >> >2017-09-01 Jakub Jelinek <jakub@redhat.com> >> > >> > PR sanitizer/81981 >> > * gimple-fold.c (gimple_fold_call): Optimize away useless UBSAN_PTR >> > and UBSAN_BOUNDS internal calls. Clean up IFN_UBSAN_OBJECT_SIZE >> > handling. >> > >> > * gcc.dg/ubsan/pr81981.c: New test. >> > >> >--- gcc/gimple-fold.c.jj 2017-08-10 02:31:21.000000000 +0200 >> >+++ gcc/gimple-fold.c 2017-08-29 18:50:49.993673432 +0200 >> >@@ -3938,11 +3938,23 @@ gimple_fold_call (gimple_stmt_iterator * >> > gimple_call_arg (stmt, 2)); >> > break; >> > case IFN_UBSAN_OBJECT_SIZE: >> >- if (integer_all_onesp (gimple_call_arg (stmt, 2)) >> >- || (TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST >> >- && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST >> >- && tree_int_cst_le (gimple_call_arg (stmt, 1), >> >- gimple_call_arg (stmt, 2)))) >> >+ { >> >+ tree offset = gimple_call_arg (stmt, 1); >> >+ tree objsize = gimple_call_arg (stmt, 2); >> >+ if (integer_all_onesp (objsize) >> >+ || (TREE_CODE (offset) == INTEGER_CST >> >+ && TREE_CODE (objsize) == INTEGER_CST >> >+ && tree_int_cst_le (offset, objsize))) >> >+ { >> >+ gsi_replace (gsi, gimple_build_nop (), false); >> >+ unlink_stmt_vdef (stmt); >> >+ release_defs (stmt); >> >+ return true; >> >+ } >> >+ } >> >+ break; >> >+ case IFN_UBSAN_PTR: >> >+ if (integer_zerop (gimple_call_arg (stmt, 1))) >> > { >> > gsi_replace (gsi, gimple_build_nop (), false); >> > unlink_stmt_vdef (stmt); >> >@@ -3950,6 +3962,25 @@ gimple_fold_call (gimple_stmt_iterator * >> > return true; >> > } >> > break; >> >+ case IFN_UBSAN_BOUNDS: >> >+ { >> >+ tree index = gimple_call_arg (stmt, 1); >> >+ tree bound = gimple_call_arg (stmt, 2); >> >+ if (TREE_CODE (index) == INTEGER_CST >> >+ && TREE_CODE (bound) == INTEGER_CST) >> >+ { >> >+ index = fold_convert (TREE_TYPE (bound), index); >> >+ if (TREE_CODE (index) == INTEGER_CST >> >+ && tree_int_cst_le (index, bound)) >> >+ { >> >+ gsi_replace (gsi, gimple_build_nop (), false); >> >+ unlink_stmt_vdef (stmt); >> >+ release_defs (stmt); >> >+ return true; >> >+ } >> >+ } >> >+ } >> >+ break; >> > case IFN_GOACC_DIM_SIZE: >> > case IFN_GOACC_DIM_POS: >> > result = fold_internal_goacc_dim (stmt); >> >--- gcc/testsuite/gcc.dg/ubsan/pr81981.c.jj 2017-08-29 >> >18:54:33.826107761 +0200 >> >+++ gcc/testsuite/gcc.dg/ubsan/pr81981.c 2017-08-29 >18:55:36.721386827 >> >+0200 >> >@@ -0,0 +1,21 @@ >> >+/* PR sanitizer/81981 */ >> >+/* { dg-do compile } */ >> >+/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined >> >-ffat-lto-objects" } */ >> >+ >> >+int v; >> >+ >> >+int >> >+foo (int i) >> >+{ >> >+ int t[1], u[1]; >> >+ int n = 0; >> >+ >> >+ if (i) >> >+ { >> >+ t[n] = i; >> >+ u[0] = i; >> >+ } >> >+ >> >+ v = u[0]; /* { dg-warning "may be used uninitialized in this >> >function" } */ >> >+ return t[0]; /* { dg-warning "may be used uninitialized in this >> >function" } */ >> >+} >> > >> > Jakub > > Jakub
--- gcc/gimple-fold.c.jj 2017-08-10 02:31:21.000000000 +0200 +++ gcc/gimple-fold.c 2017-08-29 18:50:49.993673432 +0200 @@ -3938,11 +3938,23 @@ gimple_fold_call (gimple_stmt_iterator * gimple_call_arg (stmt, 2)); break; case IFN_UBSAN_OBJECT_SIZE: - if (integer_all_onesp (gimple_call_arg (stmt, 2)) - || (TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST - && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST - && tree_int_cst_le (gimple_call_arg (stmt, 1), - gimple_call_arg (stmt, 2)))) + { + tree offset = gimple_call_arg (stmt, 1); + tree objsize = gimple_call_arg (stmt, 2); + if (integer_all_onesp (objsize) + || (TREE_CODE (offset) == INTEGER_CST + && TREE_CODE (objsize) == INTEGER_CST + && tree_int_cst_le (offset, objsize))) + { + gsi_replace (gsi, gimple_build_nop (), false); + unlink_stmt_vdef (stmt); + release_defs (stmt); + return true; + } + } + break; + case IFN_UBSAN_PTR: + if (integer_zerop (gimple_call_arg (stmt, 1))) { gsi_replace (gsi, gimple_build_nop (), false); unlink_stmt_vdef (stmt); @@ -3950,6 +3962,25 @@ gimple_fold_call (gimple_stmt_iterator * return true; } break; + case IFN_UBSAN_BOUNDS: + { + tree index = gimple_call_arg (stmt, 1); + tree bound = gimple_call_arg (stmt, 2); + if (TREE_CODE (index) == INTEGER_CST + && TREE_CODE (bound) == INTEGER_CST) + { + index = fold_convert (TREE_TYPE (bound), index); + if (TREE_CODE (index) == INTEGER_CST + && tree_int_cst_le (index, bound)) + { + gsi_replace (gsi, gimple_build_nop (), false); + unlink_stmt_vdef (stmt); + release_defs (stmt); + return true; + } + } + } + break; case IFN_GOACC_DIM_SIZE: case IFN_GOACC_DIM_POS: result = fold_internal_goacc_dim (stmt); --- gcc/testsuite/gcc.dg/ubsan/pr81981.c.jj 2017-08-29 18:54:33.826107761 +0200 +++ gcc/testsuite/gcc.dg/ubsan/pr81981.c 2017-08-29 18:55:36.721386827 +0200 @@ -0,0 +1,21 @@ +/* PR sanitizer/81981 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined -ffat-lto-objects" } */ + +int v; + +int +foo (int i) +{ + int t[1], u[1]; + int n = 0; + + if (i) + { + t[n] = i; + u[0] = i; + } + + v = u[0]; /* { dg-warning "may be used uninitialized in this function" } */ + return t[0]; /* { dg-warning "may be used uninitialized in this function" } */ +}