On Thu, Apr 3, 2014 at 9:22 PM, Jeff Law <l...@redhat.com> wrote: > > > As noted in the PR, there are a few insns in the ARM backend which use > const_int_operand as a predicate, but which have constraints like "I" or > "M". > > With the predicate accepting all constants, it's possible for a pass such as > combine to create an insn where the constant operand matches the loose > predicate, but will not match the tighter constraint. WIth no other > alternatives to choose from, lra/reload won't be able to fixup the insn. > > The right way (IMHO) is to tighten the predicate in these cases. This patch > introduces const_int_I_operand and const_int_M_operand. > > Bootstrapped on arm7l-unknown-linux-gnu (without java which fails for > unrelated reasons) and regression tested. One system didn't have GDB > installed, so the atomic and guality tests were noisy and due to time > constraints, I haven't re-run them. > > OK for the trunk?
This is OK and thanks for fixing this. Ramana > > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index 8d0c021..6c170d3 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,15 @@ > +2014-04-03 Jeff Law <l...@redhat.com> > + > + PR target/60657 > + * arm/predicates.md (const_int_I_operand): New predicate. > + (const_int_M_operand): Similarly. > + * arm/arm.md (insv_zero): Use const_int_M_operand instead of > + const_int_operand. > + (insv_t2, extv_reg, extzv_t2): Likewise. > + (load_multiple_with_writeback): Similarly for const_int_I_operand. > + (pop_multiple_with_writeback_and_return): Likewise. > + (vfp_pop_multiple_with_writeback): Likewise > + > 2014-04-03 Richard Biener <rguent...@suse.de> > > * tree-streamer.h (struct streamer_tree_cache_d): Add next_idx > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md > index 4df24a2..4b81ee2 100644 > --- a/gcc/config/arm/arm.md > +++ b/gcc/config/arm/arm.md > @@ -2784,8 +2784,8 @@ > > (define_insn "insv_zero" > [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") > - (match_operand:SI 1 "const_int_operand" "M") > - (match_operand:SI 2 "const_int_operand" "M")) > + (match_operand:SI 1 "const_int_M_operand" "M") > + (match_operand:SI 2 "const_int_M_operand" "M")) > (const_int 0))] > "arm_arch_thumb2" > "bfc%?\t%0, %2, %1" > @@ -2797,8 +2797,8 @@ > > (define_insn "insv_t2" > [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") > - (match_operand:SI 1 "const_int_operand" "M") > - (match_operand:SI 2 "const_int_operand" "M")) > + (match_operand:SI 1 "const_int_M_operand" "M") > + (match_operand:SI 2 "const_int_M_operand" "M")) > (match_operand:SI 3 "s_register_operand" "r"))] > "arm_arch_thumb2" > "bfi%?\t%0, %3, %2, %1" > @@ -4480,8 +4480,8 @@ > (define_insn "*extv_reg" > [(set (match_operand:SI 0 "s_register_operand" "=r") > (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") > - (match_operand:SI 2 "const_int_operand" "M") > - (match_operand:SI 3 "const_int_operand" "M")))] > + (match_operand:SI 2 "const_int_M_operand" "M") > + (match_operand:SI 3 "const_int_M_operand" "M")))] > "arm_arch_thumb2" > "sbfx%?\t%0, %1, %3, %2" > [(set_attr "length" "4") > @@ -4493,8 +4493,8 @@ > (define_insn "extzv_t2" > [(set (match_operand:SI 0 "s_register_operand" "=r") > (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") > - (match_operand:SI 2 "const_int_operand" "M") > - (match_operand:SI 3 "const_int_operand" "M")))] > + (match_operand:SI 2 "const_int_M_operand" "M") > + (match_operand:SI 3 "const_int_M_operand" "M")))] > "arm_arch_thumb2" > "ubfx%?\t%0, %1, %3, %2" > [(set_attr "length" "4") > @@ -12073,7 +12073,7 @@ > [(match_parallel 0 "load_multiple_operation" > [(set (match_operand:SI 1 "s_register_operand" "+rk") > (plus:SI (match_dup 1) > - (match_operand:SI 2 "const_int_operand" "I"))) > + (match_operand:SI 2 "const_int_I_operand" "I"))) > (set (match_operand:SI 3 "s_register_operand" "=rk") > (mem:SI (match_dup 1))) > ])] > @@ -12102,7 +12102,7 @@ > [(return) > (set (match_operand:SI 1 "s_register_operand" "+rk") > (plus:SI (match_dup 1) > - (match_operand:SI 2 "const_int_operand" "I"))) > + (match_operand:SI 2 "const_int_I_operand" "I"))) > (set (match_operand:SI 3 "s_register_operand" "=rk") > (mem:SI (match_dup 1))) > ])] > @@ -12155,7 +12155,7 @@ > [(match_parallel 0 "pop_multiple_fp" > [(set (match_operand:SI 1 "s_register_operand" "+rk") > (plus:SI (match_dup 1) > - (match_operand:SI 2 "const_int_operand" "I"))) > + (match_operand:SI 2 "const_int_I_operand" "I"))) > (set (match_operand:DF 3 "vfp_hard_register_operand" "") > (mem:DF (match_dup 1)))])] > "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" > diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md > index ce5c9a8..6273e88 100644 > --- a/gcc/config/arm/predicates.md > +++ b/gcc/config/arm/predicates.md > @@ -153,6 +153,14 @@ > (ior (match_operand 0 "arm_rhs_operand") > (match_operand 0 "memory_operand"))) > > +(define_predicate "const_int_I_operand" > + (and (match_operand 0 "const_int_operand") > + (match_test "satisfies_constraint_I (op)"))) > + > +(define_predicate "const_int_M_operand" > + (and (match_operand 0 "const_int_operand") > + (match_test "satisfies_constraint_M (op)"))) > + > ;; This doesn't have to do much because the constant is already checked > ;; in the shift_operator predicate. > (define_predicate "shift_amount_operand" > diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog > index 3a58dc2..94d354c 100644 > --- a/gcc/testsuite/ChangeLog > +++ b/gcc/testsuite/ChangeLog > @@ -1,3 +1,8 @@ > +2014-04-03 Jeff Law <l...@redhat.com> > + > + PR target/60657 > + * gcc.target/arm/pr60657.c: New test. > + > 2014-04-03 Richard Biener <rguent...@suse.de> > > PR tree-optimization/60740 > diff --git a/gcc/testsuite/gcc.target/arm/pr60657.c > b/gcc/testsuite/gcc.target/arm/pr60657.c > new file mode 100644 > index 0000000..d70e58c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/pr60657.c > @@ -0,0 +1,13 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -march=armv7-a" } */ > + > + > +void foo (void); > + > +void > +bar (int x, int y) > +{ > + y = 9999; > + if (x & (1 << y)) > + foo (); > + >