On Mon, May 5, 2025 at 12:53 PM Andrew Pinski <pins...@gmail.com> wrote: > > On Mon, May 5, 2025 at 12:00 AM Richard Biener > <richard.guent...@gmail.com> wrote: > > > > On Mon, May 5, 2025 at 3:45 AM Andrew Pinski <quic_apin...@quicinc.com> > > wrote: > > > > > > Like the patch to phiopt (r15-4033-g1f619fe25925a5f7), this adds rewriting > > > of VCE to > > > gimple_with_undefined_signed_overflow/rewrite_to_defined_overflow. > > > I have not seen a case yet for needing this rewrite but this step is > > > needed > > > to use gimple_with_undefined_signed_overflow/rewrite_to_defined_overflow > > > from > > > phiopt. > > > > So what again was the "undefinedness" here? And why is this relevant > > for _signed overflow_? Wouldn't it be at least no problem to V_C_E > > a lower-precision value to a higher precision? > > First has nothing to do with `signed integer overflow`, I should have > renamed the functions after this. > But the undefinedness is that on the condition VCE is valid since it > is known to be either 0/1. > But once you move the VCE to be unconditional, the value coming out of > the VCE might be out of range for the precision (in this case 0/1). > > An example is from PR 116098: > ``` > <bb 4> [local count: 1073741824]: > if (value_7 == 0) > goto <bb 5>; [50.00%] > else > goto <bb 6>; [50.00%] > > <bb 5> [local count: 536870912]: > <L2>: > _6 = VIEW_CONVERT_EXPR<_Bool>(value$8_8); > > <bb 6> [local count: 1073741824]: > # _2 = PHI <_6(5), 1(4)> > ``` > > And then we move the VCE from being conditional to being unconditional > and assume the resulting bool will be well defined. > > Note I did found a testcase which shows the issue now on the trunk > (from GCC 14 onwards) without any new changes, PR 120122. This patch > will fix that case since we are pulling the VCE out of the loop but > not rewriting it.
One thing I left out, is that once you move the VCE out of the loop/condition. > if (value_7 == 0) > goto <bb 5>; [50.00%] > else > goto <bb 6>; [50.00%] > > <bb 5> [local count: 536870912]: > <L2>: > _6 = VIEW_CONVERT_EXPR<_Bool>(value$8_8); > > <bb 6> [local count: 1073741824]: > # _2 = PHI <_6(5), 1(4)> can (and will) be converted to just: t = value_7 != 0; _2 = _6 | t since this is `(value_7 == 0) ? _6 : 1` or `(value_7 != 0) ? 1 : _6` and since _6 is a boolean value it can be or'ed with the original case. But without the rewrite, _6 might be something that is not 0/1 and things go downhill from there. Thanks, Andrew > > > > > Maybe we should simply reject V_C_Es of non-mode-precision entities > > on GIMPLE, much like we reject BIT_FIELD_REFs of those. > > I am all for that, SRA is what produces the majority of them. > > > > > > Bootstrappd and tested on x86_64-linux-gnu. > > > > > > gcc/ChangeLog: > > > > > > PR tree-optimization/116939 > > > * gimple-fold.cc (gimple_with_undefined_signed_overflow): Return > > > true > > > for VCE with integral types. > > > (rewrite_to_defined_overflow): Handle VCE rewriting to a cast. > > > > > > Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> > > > --- > > > gcc/gimple-fold.cc | 30 ++++++++++++++++++++++++++++-- > > > 1 file changed, 28 insertions(+), 2 deletions(-) > > > > > > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc > > > index c060ef81a42..a6a7fcbb8c1 100644 > > > --- a/gcc/gimple-fold.cc > > > +++ b/gcc/gimple-fold.cc > > > @@ -10602,6 +10602,14 @@ gimple_with_undefined_signed_overflow (gimple > > > *stmt) > > > if (!INTEGRAL_TYPE_P (lhs_type) > > > && !POINTER_TYPE_P (lhs_type)) > > > return false; > > > + tree rhs = gimple_assign_rhs1 (stmt); > > > + /* VCE from integral types to another integral types but with > > > + different precisions need to be changed into casts > > > + to be well defined. */ > > > + if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR > > > + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))) > > > + && is_gimple_val (TREE_OPERAND (rhs, 0))) > > > + return true; > > > if (!TYPE_OVERFLOW_UNDEFINED (lhs_type)) > > > return false; > > > if (!arith_code_with_undefined_signed_overflow > > > @@ -10630,10 +10638,28 @@ rewrite_to_defined_overflow > > > (gimple_stmt_iterator *gsi, gimple *stmt, > > > "overflow "); > > > print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); > > > } > > > - > > > + gimple_seq stmts = NULL; > > > + /* VCE from integral types to another integral types but with > > > + different precisions need to be changed into casts > > > + to be well defined. */ > > > + if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR) > > > + { > > > + tree rhs = gimple_assign_rhs1 (stmt); > > > + tree new_rhs = TREE_OPERAND (rhs, 0); > > > + gcc_assert (is_gimple_val (new_rhs)); > > > + gimple_assign_set_rhs_code (stmt, NOP_EXPR); > > > + gimple_assign_set_rhs1 (stmt, new_rhs); > > > + if (in_place) > > > + update_stmt (stmt); > > > + else > > > + { > > > + gimple_set_modified (stmt, true); > > > + gimple_seq_add_stmt (&stmts, stmt); > > > + } > > > + return stmts; > > > + } > > > tree lhs = gimple_assign_lhs (stmt); > > > tree type = unsigned_type_for (TREE_TYPE (lhs)); > > > - gimple_seq stmts = NULL; > > > if (gimple_assign_rhs_code (stmt) == ABS_EXPR) > > > gimple_assign_set_rhs_code (stmt, ABSU_EXPR); > > > else > > > -- > > > 2.34.1 > > >