Message ID | 20160315131833.GV3017@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Tue, Mar 15, 2016 at 02:18:33PM +0100, Jakub Jelinek wrote: > So do you prefer this instead? > > 2016-03-15 Jakub Jelinek <jakub@redhat.com> > > PR rtl-optimization/70222 > * combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT > optimization if mode is different from result_mode, queue up masking > of the result in outer_op. Formatting fix. > > * gcc.c-torture/execute/pr70222-1.c: New test. > * gcc.c-torture/execute/pr70222-2.c: New test. This one looks fine, too (if it works ;-) ) Segher > --- gcc/combine.c.jj 2016-03-14 23:18:37.958408627 +0100 > +++ gcc/combine.c 2016-03-15 14:08:34.754434506 +0100 > @@ -10524,9 +10524,19 @@ simplify_shift_const_1 (enum rtx_code co > && CONST_INT_P (XEXP (varop, 0)) > && !CONST_INT_P (XEXP (varop, 1))) > { > + /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make > + sure the result will be masked. See PR70222. */ > + if (code == LSHIFTRT > + && mode != result_mode > + && !merge_outer_ops (&outer_op, &outer_const, AND, > + GET_MODE_MASK (result_mode) > + >> orig_count, result_mode, > + &complement_p)) > + break; > + > rtx new_rtx = simplify_const_binary_operation (code, mode, > - XEXP (varop, 0), > - GEN_INT (count)); > + XEXP (varop, 0), > + GEN_INT (count)); > varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1)); > count = 0; > continue; > --- gcc/testsuite/gcc.c-torture/execute/pr70222-1.c.jj 2016-03-15 11:30:41.657000384 +0100 > +++ gcc/testsuite/gcc.c-torture/execute/pr70222-1.c 2016-03-15 11:30:41.657000384 +0100 > @@ -0,0 +1,30 @@ > +/* PR rtl-optimization/70222 */ > + > +int a = 1; > +unsigned int b = 2; > +int c = 0; > +int d = 0; > + > +void > +foo () > +{ > + int e = ((-(c >= c)) < b) > ((int) (-1ULL >> ((a / a) * 15))); > + d = -e; > +} > + > +__attribute__((noinline, noclone)) void > +bar (int x) > +{ > + if (x != -1) > + __builtin_abort (); > +} > + > +int > +main () > +{ > +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 > + foo (); > + bar (d); > +#endif > + return 0; > +} > --- gcc/testsuite/gcc.c-torture/execute/pr70222-2.c.jj 2016-03-15 11:36:13.273366841 +0100 > +++ gcc/testsuite/gcc.c-torture/execute/pr70222-2.c 2016-03-15 11:36:18.156298614 +0100 > @@ -0,0 +1,20 @@ > +/* PR rtl-optimization/70222 */ > + > +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 > +__attribute__((noinline, noclone)) unsigned int > +foo (int x) > +{ > + unsigned long long y = -1ULL >> x; > + return (unsigned int) y >> 31; > +} > +#endif > + > +int > +main () > +{ > +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 > + if (foo (15) != 1 || foo (32) != 1 || foo (33) != 0) > + __builtin_abort (); > +#endif > + return 0; > +}
On Tue, Mar 15, 2016 at 09:50:44AM -0500, Segher Boessenkool wrote: > On Tue, Mar 15, 2016 at 02:18:33PM +0100, Jakub Jelinek wrote: > > So do you prefer this instead? > > > > 2016-03-15 Jakub Jelinek <jakub@redhat.com> > > > > PR rtl-optimization/70222 > > * combine.c (simplify_shift_const_1): For A >> B >> C LSHIFTRT > > optimization if mode is different from result_mode, queue up masking > > of the result in outer_op. Formatting fix. > > > > * gcc.c-torture/execute/pr70222-1.c: New test. > > * gcc.c-torture/execute/pr70222-2.c: New test. > > This one looks fine, too (if it works ;-) ) Passed bootstrap/regtest on x86_64-linux and i686-linux, and triggers solely on the new testcases, nothing else. Committed now. Jakub
--- gcc/combine.c.jj 2016-03-14 23:18:37.958408627 +0100 +++ gcc/combine.c 2016-03-15 14:08:34.754434506 +0100 @@ -10524,9 +10524,19 @@ simplify_shift_const_1 (enum rtx_code co && CONST_INT_P (XEXP (varop, 0)) && !CONST_INT_P (XEXP (varop, 1))) { + /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make + sure the result will be masked. See PR70222. */ + if (code == LSHIFTRT + && mode != result_mode + && !merge_outer_ops (&outer_op, &outer_const, AND, + GET_MODE_MASK (result_mode) + >> orig_count, result_mode, + &complement_p)) + break; + rtx new_rtx = simplify_const_binary_operation (code, mode, - XEXP (varop, 0), - GEN_INT (count)); + XEXP (varop, 0), + GEN_INT (count)); varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1)); count = 0; continue; --- gcc/testsuite/gcc.c-torture/execute/pr70222-1.c.jj 2016-03-15 11:30:41.657000384 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr70222-1.c 2016-03-15 11:30:41.657000384 +0100 @@ -0,0 +1,30 @@ +/* PR rtl-optimization/70222 */ + +int a = 1; +unsigned int b = 2; +int c = 0; +int d = 0; + +void +foo () +{ + int e = ((-(c >= c)) < b) > ((int) (-1ULL >> ((a / a) * 15))); + d = -e; +} + +__attribute__((noinline, noclone)) void +bar (int x) +{ + if (x != -1) + __builtin_abort (); +} + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + foo (); + bar (d); +#endif + return 0; +} --- gcc/testsuite/gcc.c-torture/execute/pr70222-2.c.jj 2016-03-15 11:36:13.273366841 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr70222-2.c 2016-03-15 11:36:18.156298614 +0100 @@ -0,0 +1,20 @@ +/* PR rtl-optimization/70222 */ + +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 +__attribute__((noinline, noclone)) unsigned int +foo (int x) +{ + unsigned long long y = -1ULL >> x; + return (unsigned int) y >> 31; +} +#endif + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + if (foo (15) != 1 || foo (32) != 1 || foo (33) != 0) + __builtin_abort (); +#endif + return 0; +}