https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70429
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |4.9.4 --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Kirill Yukhin from comment #4) > Seems like combiner performs invalid reassociation. This trivial addition to > Jakub's PR70222 fix makes test work: > > --- a/gcc/combine.c > +++ b/gcc/combine.c > @@ -10526,7 +10526,7 @@ simplify_shift_const_1 (enum rtx_code code, > machine_mode result_mode, > { > /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make > sure the result will be masked. See PR70222. */ > - if (code == LSHIFTRT > + if ((code == LSHIFTRT || code == ASHIFTRT) > && mode != result_mode > && !merge_outer_ops (&outer_op, &outer_const, AND, > GET_MODE_MASK (result_mode) That looks wrong. Consider following testcase: __attribute__((noinline, noclone)) int foo (int a) { return (int) (0x14ff6e2207db5d1fLL >> a) >> 4; } int main () { if (sizeof (int) != 4 || sizeof (long long) != 8 || __CHAR_BIT__ != 8) return 0; if (foo (1) != 0x3edae8 || foo (2) != -132158092) __builtin_abort (); return 0; } With your above patch, it will try to combine: Trying 6, 7 -> 8: Failed to match this instruction: (parallel [ (set (reg:SI 91) (and:SI (subreg:SI (ashiftrt:DI (const_int 94565568266221009 [0x14ff6e2207db5d1]) (subreg:QI (reg/v:SI 90 [ a ]) 0)) 0) (const_int 268435455 [0xfffffff]))) (clobber (reg:CC 17 flags)) ]) Failed to match this instruction: (set (reg:SI 91) (and:SI (subreg:SI (ashiftrt:DI (const_int 94565568266221009 [0x14ff6e2207db5d1]) (subreg:QI (reg/v:SI 90 [ a ]) 0)) 0) (const_int 268435455 [0xfffffff]))) and only because there is no such insn on x86, it will not miscompile it. ASHIFTRT needs corresponding sign extension, not AND.