public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] [PR103024, PR103530] support throwing compares and non-boolean types
@ 2021-12-08 3:14 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-12-08 3:14 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:b9cceea3c093cdf724eaaecbdf88ca21b8bd1f10
commit b9cceea3c093cdf724eaaecbdf88ca21b8bd1f10
Author: Alexandre Oliva <oliva@adacore.com>
Date: Sat Dec 4 03:06:00 2021 -0300
[PR103024,PR103530] support throwing compares and non-boolean types
This patch adjusts the harden-compares pass to cope with compares that
end basic blocks, and to accept non-boolean integral types whose
conversion to boolean may have been discarded.
for gcc/ChangeLog
PR tree-optimization/103024
PR middle-end/103530
* gimple-harden-conditionals.cc (non_eh_succ_edge): New.
(pass_harden_compares::execute): Accept 1-bit integral types,
and cope with throwing compares.
for gcc/testsuite/ChangeLog
PR tree-optimization/103024
PR middle-end/103530
* g++.dg/pr103024.C: New.
* g++.dg/pr103530.C: New.
Diff:
---
gcc/gimple-harden-conditionals.cc | 74 ++++++++++++++++++++++++++++++++++++---
gcc/testsuite/g++.dg/pr103024.C | 12 +++++++
gcc/testsuite/g++.dg/pr103530.C | 27 ++++++++++++++
3 files changed, 109 insertions(+), 4 deletions(-)
diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index 81867d6e427..5e709c66416 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
+#include "tree-eh.h"
#include "diagnostic.h"
#include "intl.h"
@@ -359,6 +360,24 @@ make_pass_harden_conditional_branches (gcc::context *ctxt)
return new pass_harden_conditional_branches (ctxt);
}
+/* Return the fallthru edge of a block whose other edge is an EH
+ edge. */
+static inline edge
+non_eh_succ_edge (basic_block bb)
+{
+ gcc_checking_assert (EDGE_COUNT (bb->succs) == 2);
+
+ edge ret = find_fallthru_edge (bb->succs);
+
+ int eh_idx = EDGE_SUCC (bb, 0) == ret;
+ edge eh = EDGE_SUCC (bb, eh_idx);
+
+ gcc_checking_assert (!(ret->flags & EDGE_EH)
+ && (eh->flags & EDGE_EH));
+
+ return ret;
+}
+
/* Harden boolean-yielding compares in FUN. */
unsigned int
@@ -449,7 +468,11 @@ pass_harden_compares::execute (function *fun)
if (VECTOR_TYPE_P (TREE_TYPE (op1)))
continue;
- gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE);
+ /* useless_type_conversion_p enables conversions from 1-bit
+ integer types to boolean to be discarded. */
+ gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
+ || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ && TYPE_PRECISION (TREE_TYPE (lhs)) == 1));
tree rhs = copy_ssa_name (lhs);
@@ -460,6 +483,20 @@ pass_harden_compares::execute (function *fun)
won't be debug stmts only. */
gsi_next_nondebug (&gsi_split);
+ bool throwing_compare_p = stmt_ends_bb_p (asgn);
+ if (throwing_compare_p)
+ {
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgn)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i"
+ " after a throwing compare\n",
+ gimple_bb (asgn)->index, nbb->index);
+ }
+
bool same_p = (op1 == op2);
op1 = detach_value (loc, &gsi_split, op1);
op2 = same_p ? op1 : detach_value (loc, &gsi_split, op2);
@@ -473,17 +510,46 @@ pass_harden_compares::execute (function *fun)
if (!gsi_end_p (gsi_split))
{
gsi_prev (&gsi_split);
- split_block (bb, gsi_stmt (gsi_split));
+ basic_block obb = gsi_bb (gsi_split);
+ basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
gsi_next (&gsi_split);
gcc_checking_assert (gsi_end_p (gsi_split));
single_succ_edge (bb)->goto_locus = loc;
if (dump_file)
- fprintf (dump_file, "Splitting block %i\n", bb->index);
+ fprintf (dump_file,
+ "Splitting block %i into %i"
+ " before the conditional trap branch\n",
+ obb->index, nbb->index);
+ }
+
+ /* If the check assignment must end a basic block, we can't
+ insert the conditional branch in the same block, so split
+ the block again, and prepare to insert the conditional
+ branch in the new block.
+
+ Also assign an EH region to the compare. Even though it's
+ unlikely that the hardening compare will throw after the
+ original compare didn't, the compiler won't even know that
+ it's the same compare operands, so add the EH edge anyway. */
+ if (throwing_compare_p)
+ {
+ add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn));
+ make_eh_edges (asgnck);
+
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgnck)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i after"
+ " the newly-inserted reversed throwing compare\n",
+ gimple_bb (asgnck)->index, nbb->index);
}
- gcc_checking_assert (single_succ_p (bb));
+ gcc_checking_assert (single_succ_p (gsi_bb (gsi_split)));
insert_check_and_trap (loc, &gsi_split, EDGE_TRUE_VALUE,
EQ_EXPR, lhs, rhs);
diff --git a/gcc/testsuite/g++.dg/pr103024.C b/gcc/testsuite/g++.dg/pr103024.C
new file mode 100644
index 00000000000..15e68d40213
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103024.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fnon-call-exceptions -fharden-compares -fsignaling-nans" } */
+
+struct G4ErrorMatrix {
+ G4ErrorMatrix(int);
+ ~G4ErrorMatrix();
+};
+double PropagateError_charge;
+void PropagateError() {
+ G4ErrorMatrix transf(0);
+ int field(PropagateError_charge && field);
+}
diff --git a/gcc/testsuite/g++.dg/pr103530.C b/gcc/testsuite/g++.dg/pr103530.C
new file mode 100644
index 00000000000..c1d2059542b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103530.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fharden-compares -Wno-c++11-extensions" } */
+
+enum E:bool
+{ E0, E1 };
+
+int x;
+
+E
+baz (E rtt)
+{
+ return rtt == E0 ? E1 : E0;
+}
+
+bool bar ();
+
+void
+foo (E)
+{
+ E a = x ? E1 : E0;
+ if (bar ())
+ if (bar ())
+ {
+ E b = baz (a);
+ foo (b);
+ }
+}
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [PR103024, PR103530] support throwing compares and non-boolean types
@ 2021-12-04 9:22 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-12-04 9:22 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:d67199aa8c8d8f01561c81954befcbe54e8152bd
commit d67199aa8c8d8f01561c81954befcbe54e8152bd
Author: Alexandre Oliva <oliva@adacore.com>
Date: Sat Dec 4 03:06:00 2021 -0300
[PR103024,PR103530] support throwing compares and non-boolean types
Diff:
---
gcc/gimple-harden-conditionals.cc | 74 ++++++++++++++++++++++++++++++++++++---
gcc/testsuite/g++.dg/pr103024.C | 12 +++++++
gcc/testsuite/g++.dg/pr103530.C | 27 ++++++++++++++
3 files changed, 109 insertions(+), 4 deletions(-)
diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..ee332f9e8db 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
+#include "tree-eh.h"
#include "diagnostic.h"
#include "intl.h"
@@ -304,6 +305,24 @@ make_pass_harden_conditional_branches (gcc::context *ctxt)
return new pass_harden_conditional_branches (ctxt);
}
+/* Return the fallthru edge of a block whose other edge is an EH
+ edge. */
+static inline edge
+non_eh_succ_edge (basic_block bb)
+{
+ gcc_checking_assert (EDGE_COUNT (bb->succs) == 2);
+
+ edge ret = find_fallthru_edge (bb->succs);
+
+ int eh_idx = EDGE_SUCC (bb, 0) == ret;
+ edge eh = EDGE_SUCC (bb, eh_idx);
+
+ gcc_checking_assert (!(ret->flags & EDGE_EH)
+ && (eh->flags & EDGE_EH));
+
+ return ret;
+}
+
/* Harden boolean-yielding compares in FUN. */
unsigned int
@@ -394,7 +413,11 @@ pass_harden_compares::execute (function *fun)
if (VECTOR_TYPE_P (TREE_TYPE (op1)))
continue;
- gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE);
+ /* useless_type_conversion_p enables conversions from 1-bit
+ integer types to boolean to be discarded. */
+ gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
+ || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ && TYPE_PRECISION (TREE_TYPE (lhs)) == 1));
tree rhs = copy_ssa_name (lhs);
@@ -405,6 +428,20 @@ pass_harden_compares::execute (function *fun)
won't be debug stmts only. */
gsi_next_nondebug (&gsi_split);
+ bool throwing_compare_p = stmt_ends_bb_p (asgn);
+ if (throwing_compare_p)
+ {
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgn)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i"
+ " after a throwing compare\n",
+ gimple_bb (asgn)->index, nbb->index);
+ }
+
bool same_p = (op1 == op2);
op1 = detach_value (loc, &gsi_split, op1);
op2 = same_p ? op1 : detach_value (loc, &gsi_split, op2);
@@ -418,17 +455,46 @@ pass_harden_compares::execute (function *fun)
if (!gsi_end_p (gsi_split))
{
gsi_prev (&gsi_split);
- split_block (bb, gsi_stmt (gsi_split));
+ basic_block obb = gsi_bb (gsi_split);
+ basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
gsi_next (&gsi_split);
gcc_checking_assert (gsi_end_p (gsi_split));
single_succ_edge (bb)->goto_locus = loc;
if (dump_file)
- fprintf (dump_file, "Splitting block %i\n", bb->index);
+ fprintf (dump_file,
+ "Splitting block %i into %i"
+ " before the conditional trap branch\n",
+ obb->index, nbb->index);
+ }
+
+ /* If the check assignment must end a basic block, we can't
+ insert the conditional branch in the same block, so split
+ the block again, and prepare to insert the conditional
+ branch in the new block.
+
+ Also assign an EH region to the compare. Even though it's
+ unlikely that the hardening compare will throw after the
+ original compare didn't, the compiler won't even know that
+ it's the same compare operands, so add the EH edge anyway. */
+ if (throwing_compare_p)
+ {
+ add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn));
+ make_eh_edges (asgnck);
+
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgnck)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i after"
+ " the newly-inserted reversed throwing compare\n",
+ gimple_bb (asgnck)->index, nbb->index);
}
- gcc_checking_assert (single_succ_p (bb));
+ gcc_checking_assert (single_succ_p (gsi_bb (gsi_split)));
insert_check_and_trap (loc, &gsi_split, EDGE_TRUE_VALUE,
EQ_EXPR, lhs, rhs);
diff --git a/gcc/testsuite/g++.dg/pr103024.C b/gcc/testsuite/g++.dg/pr103024.C
new file mode 100644
index 00000000000..15e68d40213
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103024.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fnon-call-exceptions -fharden-compares -fsignaling-nans" } */
+
+struct G4ErrorMatrix {
+ G4ErrorMatrix(int);
+ ~G4ErrorMatrix();
+};
+double PropagateError_charge;
+void PropagateError() {
+ G4ErrorMatrix transf(0);
+ int field(PropagateError_charge && field);
+}
diff --git a/gcc/testsuite/g++.dg/pr103530.C b/gcc/testsuite/g++.dg/pr103530.C
new file mode 100644
index 00000000000..c1d2059542b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103530.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fharden-compares -Wno-c++11-extensions" } */
+
+enum E:bool
+{ E0, E1 };
+
+int x;
+
+E
+baz (E rtt)
+{
+ return rtt == E0 ? E1 : E0;
+}
+
+bool bar ();
+
+void
+foo (E)
+{
+ E a = x ? E1 : E0;
+ if (bar ())
+ if (bar ())
+ {
+ E b = baz (a);
+ foo (b);
+ }
+}
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [PR103024, PR103530] support throwing compares and non-boolean types
@ 2021-12-04 6:12 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-12-04 6:12 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:623fabc300ffadb03defb49bfec0ca5d48356508
commit 623fabc300ffadb03defb49bfec0ca5d48356508
Author: Alexandre Oliva <oliva@adacore.com>
Date: Sat Dec 4 03:06:00 2021 -0300
[PR103024,PR103530] support throwing compares and non-boolean types
Diff:
---
gcc/gimple-harden-conditionals.cc | 74 ++++++++++++++++++++++++++++++++++++---
gcc/testsuite/g++.dg/pr103024.C | 12 +++++++
gcc/testsuite/g++.dg/pr103530.C | 27 ++++++++++++++
3 files changed, 109 insertions(+), 4 deletions(-)
diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index cfa2361d65b..ee332f9e8db 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
+#include "tree-eh.h"
#include "diagnostic.h"
#include "intl.h"
@@ -304,6 +305,24 @@ make_pass_harden_conditional_branches (gcc::context *ctxt)
return new pass_harden_conditional_branches (ctxt);
}
+/* Return the fallthru edge of a block whose other edge is an EH
+ edge. */
+static inline edge
+non_eh_succ_edge (basic_block bb)
+{
+ gcc_checking_assert (EDGE_COUNT (bb->succs) == 2);
+
+ edge ret = find_fallthru_edge (bb->succs);
+
+ int eh_idx = EDGE_SUCC (bb, 0) == ret;
+ edge eh = EDGE_SUCC (bb, eh_idx);
+
+ gcc_checking_assert (!(ret->flags & EDGE_EH)
+ && (eh->flags & EDGE_EH));
+
+ return ret;
+}
+
/* Harden boolean-yielding compares in FUN. */
unsigned int
@@ -394,7 +413,11 @@ pass_harden_compares::execute (function *fun)
if (VECTOR_TYPE_P (TREE_TYPE (op1)))
continue;
- gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE);
+ /* useless_type_conversion_p enables conversions from 1-bit
+ integer types to boolean to be discarded. */
+ gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
+ || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ && TYPE_PRECISION (TREE_TYPE (lhs)) == 1));
tree rhs = copy_ssa_name (lhs);
@@ -405,6 +428,20 @@ pass_harden_compares::execute (function *fun)
won't be debug stmts only. */
gsi_next_nondebug (&gsi_split);
+ bool throwing_compare_p = stmt_ends_bb_p (asgn);
+ if (throwing_compare_p)
+ {
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgn)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i"
+ " after a throwing compare\n",
+ gimple_bb (asgn)->index, nbb->index);
+ }
+
bool same_p = (op1 == op2);
op1 = detach_value (loc, &gsi_split, op1);
op2 = same_p ? op1 : detach_value (loc, &gsi_split, op2);
@@ -418,17 +455,46 @@ pass_harden_compares::execute (function *fun)
if (!gsi_end_p (gsi_split))
{
gsi_prev (&gsi_split);
- split_block (bb, gsi_stmt (gsi_split));
+ basic_block obb = gsi_bb (gsi_split);
+ basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
gsi_next (&gsi_split);
gcc_checking_assert (gsi_end_p (gsi_split));
single_succ_edge (bb)->goto_locus = loc;
if (dump_file)
- fprintf (dump_file, "Splitting block %i\n", bb->index);
+ fprintf (dump_file,
+ "Splitting block %i into %i"
+ " before the conditional trap branch\n",
+ obb->index, nbb->index);
+ }
+
+ /* If the check assignment must end a basic block, we can't
+ insert the conditional branch in the same block, so split
+ the block again, and prepare to insert the conditional
+ branch in the new block.
+
+ Also assign an EH region to the compare. Even though it's
+ unlikely that the hardening compare will throw after the
+ original compare didn't, the compiler won't even know that
+ it's the same compare operands, so add the EH edge anyway. */
+ if (throwing_compare_p)
+ {
+ add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn));
+ make_eh_edges (asgnck);
+
+ basic_block nbb = split_edge (non_eh_succ_edge
+ (gimple_bb (asgnck)));
+ gsi_split = gsi_start_bb (nbb);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Splitting non-EH edge from block %i into %i after"
+ " the newly-inserted reversed throwing compare\n",
+ gimple_bb (asgnck)->index, nbb->index);
}
- gcc_checking_assert (single_succ_p (bb));
+ gcc_checking_assert (single_succ_p (gsi_bb (gsi_split)));
insert_check_and_trap (loc, &gsi_split, EDGE_TRUE_VALUE,
EQ_EXPR, lhs, rhs);
diff --git a/gcc/testsuite/g++.dg/pr103024.C b/gcc/testsuite/g++.dg/pr103024.C
new file mode 100644
index 00000000000..15e68d40213
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103024.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fnon-call-exceptions -fharden-compares -fsignaling-nans" } */
+
+struct G4ErrorMatrix {
+ G4ErrorMatrix(int);
+ ~G4ErrorMatrix();
+};
+double PropagateError_charge;
+void PropagateError() {
+ G4ErrorMatrix transf(0);
+ int field(PropagateError_charge && field);
+}
diff --git a/gcc/testsuite/g++.dg/pr103530.C b/gcc/testsuite/g++.dg/pr103530.C
new file mode 100644
index 00000000000..726b0eb3427
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr103530.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fharden-compares" } */
+
+enum E:bool
+{ E0, E1 };
+
+int x;
+
+E
+baz (E rtt)
+{
+ return rtt == E0 ? E1 : E0;
+}
+
+bool bar ();
+
+void
+foo (E)
+{
+ E a = x ? E1 : E0;
+ if (bar ())
+ if (bar ())
+ {
+ E b = baz (a);
+ foo (b);
+ }
+}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-12-08 3:14 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-08 3:14 [gcc(refs/users/aoliva/heads/testme)] [PR103024, PR103530] support throwing compares and non-boolean types Alexandre Oliva
-- strict thread matches above, loose matches on Subject: below --
2021-12-04 9:22 Alexandre Oliva
2021-12-04 6:12 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).