Message ID | 20211001124306.1458223-3-aldyh@redhat.com |
---|---|
State | New |
Headers | show |
Series | Handle EQ_EXPR relation for operator_lshift. | expand |
Well, after talking with Andrew it seems that X << Y being non-zero also implies X is non-zero. So we don't even need relationals here. So, I leave gori relationals in his capable hands, while I test this much simpler patch which fixes the PR with no additional infrastructure ;-). Will push pending tests. Aldy On Fri, Oct 1, 2021 at 2:43 PM Aldy Hernandez <aldyh@redhat.com> wrote: > > Knowing that X << X is non-zero means X is also non-zero. This patch > teaches this this to range-ops. > > As usual, the big twiddling experts could come up with all sorts of > fancy enhancements in this area, and we welcome all patches :). > > I will push this pending tests. > > gcc/ChangeLog: > > PR tree-optimization/102546 > * range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR > relation. > --- > gcc/range-op.cc | 19 ++++++++++++++++--- > gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++++++++++++++++++++++ > 2 files changed, 39 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > index 5e37133026d..53f3be4266e 100644 > --- a/gcc/range-op.cc > +++ b/gcc/range-op.cc > @@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange &r, > tree type, > const irange &lhs, > const irange &op2, > - relation_kind rel ATTRIBUTE_UNUSED) const > + relation_kind rel) const > { > tree shift_amount; > + int_range<2> adjust (type); > + > + if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type))) > + adjust.set_nonzero (type); > + > if (op2.singleton_p (&shift_amount)) > { > wide_int shift = wi::to_wide (shift_amount); > @@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange &r, > if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type), > TYPE_PRECISION (op2.type ())), > UNSIGNED)) > - return false; > + goto done; > if (shift == 0) > { > r = lhs; > + r.intersect (adjust); > return true; > } > > @@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange &r, > > if (utype != type) > range_cast (r, type); > + r.intersect (adjust); > return true; > } > - return false; > + > + done: > + if (adjust.varying_p ()) > + return false; > + > + r = adjust; > + return true; > } > > bool > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > new file mode 100644 > index 00000000000..4bd98747732 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > @@ -0,0 +1,23 @@ > +// { dg-do compile } > +// { dg-options "-O3 -fdump-tree-optimized" } > + > +static int a; > +static char b, c, d; > +void bar(void); > +void foo(void); > + > +int main() { > + int f = 0; > + for (; f <= 5; f++) { > + bar(); > + b = b && f; > + d = f << f; > + if (!(a >= d || f)) > + foo(); > + c = 1; > + for (; c; c = 0) > + ; > + } > +} > + > +// { dg-final { scan-tree-dump-not "foo" "optimized" } } > -- > 2.31.1 >
Bah. The range was being clobbered half way through the calculation. Tested on x86-64 Linux. Pushed. On Fri, Oct 1, 2021 at 4:52 PM Aldy Hernandez <aldyh@redhat.com> wrote: > > Well, after talking with Andrew it seems that X << Y being non-zero > also implies X is non-zero. So we don't even need relationals here. > > So, I leave gori relationals in his capable hands, while I test this > much simpler patch which fixes the PR with no additional > infrastructure ;-). > > Will push pending tests. > Aldy > > On Fri, Oct 1, 2021 at 2:43 PM Aldy Hernandez <aldyh@redhat.com> wrote: > > > > Knowing that X << X is non-zero means X is also non-zero. This patch > > teaches this this to range-ops. > > > > As usual, the big twiddling experts could come up with all sorts of > > fancy enhancements in this area, and we welcome all patches :). > > > > I will push this pending tests. > > > > gcc/ChangeLog: > > > > PR tree-optimization/102546 > > * range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR > > relation. > > --- > > gcc/range-op.cc | 19 ++++++++++++++++--- > > gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++++++++++++++++++++++ > > 2 files changed, 39 insertions(+), 3 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > > > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > > index 5e37133026d..53f3be4266e 100644 > > --- a/gcc/range-op.cc > > +++ b/gcc/range-op.cc > > @@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange &r, > > tree type, > > const irange &lhs, > > const irange &op2, > > - relation_kind rel ATTRIBUTE_UNUSED) const > > + relation_kind rel) const > > { > > tree shift_amount; > > + int_range<2> adjust (type); > > + > > + if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type))) > > + adjust.set_nonzero (type); > > + > > if (op2.singleton_p (&shift_amount)) > > { > > wide_int shift = wi::to_wide (shift_amount); > > @@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange &r, > > if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type), > > TYPE_PRECISION (op2.type ())), > > UNSIGNED)) > > - return false; > > + goto done; > > if (shift == 0) > > { > > r = lhs; > > + r.intersect (adjust); > > return true; > > } > > > > @@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange &r, > > > > if (utype != type) > > range_cast (r, type); > > + r.intersect (adjust); > > return true; > > } > > - return false; > > + > > + done: > > + if (adjust.varying_p ()) > > + return false; > > + > > + r = adjust; > > + return true; > > } > > > > bool > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > > new file mode 100644 > > index 00000000000..4bd98747732 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c > > @@ -0,0 +1,23 @@ > > +// { dg-do compile } > > +// { dg-options "-O3 -fdump-tree-optimized" } > > + > > +static int a; > > +static char b, c, d; > > +void bar(void); > > +void foo(void); > > + > > +int main() { > > + int f = 0; > > + for (; f <= 5; f++) { > > + bar(); > > + b = b && f; > > + d = f << f; > > + if (!(a >= d || f)) > > + foo(); > > + c = 1; > > + for (; c; c = 0) > > + ; > > + } > > +} > > + > > +// { dg-final { scan-tree-dump-not "foo" "optimized" } } > > -- > > 2.31.1 > >
On 10/2/2021 1:50 PM, Aldy Hernandez via Gcc-patches wrote: > Bah. The range was being clobbered half way through the calculation. > > Tested on x86-64 Linux. > > Pushed. > > On Fri, Oct 1, 2021 at 4:52 PM Aldy Hernandez <aldyh@redhat.com> wrote: >> Well, after talking with Andrew it seems that X << Y being non-zero >> also implies X is non-zero. So we don't even need relationals here. >> >> So, I leave gori relationals in his capable hands, while I test this >> much simpler patch which fixes the PR with no additional >> infrastructure ;-). >> >> Will push pending tests. >> Aldy >> >> On Fri, Oct 1, 2021 at 2:43 PM Aldy Hernandez <aldyh@redhat.com> wrote: >>> Knowing that X << X is non-zero means X is also non-zero. This patch >>> teaches this this to range-ops. >>> >>> As usual, the big twiddling experts could come up with all sorts of >>> fancy enhancements in this area, and we welcome all patches :). >>> >>> I will push this pending tests. >>> >>> gcc/ChangeLog: >>> >>> PR tree-optimization/102546 >>> * range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR >>> relation. I'm going to assume this also fixes a similar ICE building the linux kernel. One less thing to bisect today :-) jeff
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 5e37133026d..53f3be4266e 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel ATTRIBUTE_UNUSED) const + relation_kind rel) const { tree shift_amount; + int_range<2> adjust (type); + + if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type))) + adjust.set_nonzero (type); + if (op2.singleton_p (&shift_amount)) { wide_int shift = wi::to_wide (shift_amount); @@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange &r, if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type), TYPE_PRECISION (op2.type ())), UNSIGNED)) - return false; + goto done; if (shift == 0) { r = lhs; + r.intersect (adjust); return true; } @@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange &r, if (utype != type) range_cast (r, type); + r.intersect (adjust); return true; } - return false; + + done: + if (adjust.varying_p ()) + return false; + + r = adjust; + return true; } bool diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c new file mode 100644 index 00000000000..4bd98747732 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O3 -fdump-tree-optimized" } + +static int a; +static char b, c, d; +void bar(void); +void foo(void); + +int main() { + int f = 0; + for (; f <= 5; f++) { + bar(); + b = b && f; + d = f << f; + if (!(a >= d || f)) + foo(); + c = 1; + for (; c; c = 0) + ; + } +} + +// { dg-final { scan-tree-dump-not "foo" "optimized" } }