Jakub Jelinek <ja...@redhat.com> writes: > Hi! > > The following testcase ICEs in final_scan_insn_1. The problem is in the > @aarch64_compare_and_swaphi define_insn_and_split, since 9 it uses > aarch64_plushi_operand predicate for the "expected value" operand, which > allows either 0..0xfff constants or 0x1000..0xf000 constants (i.e. HImode > values which when zero extended are either 0..0xfff or (0..0xfff) << 12). > The problem is that RA doesn't care about predicates, it honors just > constraints and the used constraint on the operand is n, which means any > HImode CONST_SCALAR_INT. In the testcase LRA thus propagates the -1 > value into the insn. > This is a define_insn_and_split which requires mandatory split. > But during split2 pass, we check the predicate (and don't check > constraints), which fails and thus we don't split it and during final ICE > because the mandatory splitting didn't happen. > > The following patch fixes it by adding a matching constraint to the > predicate and using it. > > Bootstrapped/regtested on aarch64-linux, ok for trunk?
OK, thanks. Richard > 2020-03-31 Jakub Jelinek <ja...@redhat.com> > > PR target/94368 > * config/aarch64/constraints.md (Uph): New constraint. > * config/aarch64/atomics.md (cas_short_expected_imm): New mode attr. > (@aarch64_compare_and_swap<mode>): Use it instead of n in operand 2's > constraint. > > * gcc.dg/pr94368.c: New test. > > --- gcc/config/aarch64/constraints.md.jj 2020-01-17 19:35:54.101144322 > +0100 > +++ gcc/config/aarch64/constraints.md 2020-03-30 11:39:29.554441681 +0200 > @@ -233,6 +233,13 @@ (define_constraint "Up3" > (and (match_code "const_int") > (match_test "(unsigned) exact_log2 (ival) <= 4"))) > > +(define_constraint "Uph" > + "@internal > + A constraint that matches HImode integers zero extendable to > + SImode plus_operand." > + (and (match_code "const_int") > + (match_test "aarch64_plushi_immediate (op, VOIDmode)"))) > + > (define_memory_constraint "Q" > "A memory address which uses a single base register with no offset." > (and (match_code "mem") > --- gcc/config/aarch64/atomics.md.jj 2020-01-17 14:46:41.464792827 +0100 > +++ gcc/config/aarch64/atomics.md 2020-03-30 11:42:02.256180919 +0200 > @@ -38,6 +38,8 @@ (define_expand "@atomic_compare_and_swap > > (define_mode_attr cas_short_expected_pred > [(QI "aarch64_reg_or_imm") (HI "aarch64_plushi_operand")]) > +(define_mode_attr cas_short_expected_imm > + [(QI "n") (HI "Uph")]) > > (define_insn_and_split "@aarch64_compare_and_swap<mode>" > [(set (reg:CC CC_REGNUM) ;; bool out > @@ -47,7 +49,8 @@ (define_insn_and_split "@aarch64_compare > (match_operand:SHORT 1 "aarch64_sync_memory_operand" "+Q"))) ;; memory > (set (match_dup 1) > (unspec_volatile:SHORT > - [(match_operand:SHORT 2 "<cas_short_expected_pred>" "rn") ;; > expected > + [(match_operand:SHORT 2 "<cas_short_expected_pred>" > + "r<cas_short_expected_imm>") ;; expected > (match_operand:SHORT 3 "aarch64_reg_or_zero" "rZ") ;; desired > (match_operand:SI 4 "const_int_operand") ;; > is_weak > (match_operand:SI 5 "const_int_operand") ;; mod_s > --- gcc/testsuite/gcc.dg/pr94368.c.jj 2020-03-30 11:47:18.573497812 +0200 > +++ gcc/testsuite/gcc.dg/pr94368.c 2020-03-30 11:25:54.002642049 +0200 > @@ -0,0 +1,25 @@ > +/* PR target/94368 */ > +/* { dg-do compile { target fpic } } */ > +/* { dg-options "-fpic -O1 -fcommon" } */ > + > +int b, c, d, e, f, h; > +short g; > +int foo (int) __attribute__ ((__const__)); > + > +void > +bar (void) > +{ > + while (1) > + { > + while (1) > + { > + __atomic_load_n (&e, 0); > + if (foo (2)) > + __sync_val_compare_and_swap (&c, 0, f); > + b = 1; > + if (h == e) > + break; > + } > + __sync_val_compare_and_swap (&g, -1, f); > + } > +} > > Jakub