From 69128a1730ce956e536faf2f0b0e3f7326e5a52c Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 6 Apr 2018 22:30:05 +0000 Subject: [PATCH] re PR middle-end/85196 (ICE in extract_insn, at recog.c:2311: unrecognizable insn) PR target/85196 * config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands based on LABEL_REF. Remove useless assertion. (pic_address_needs_scratch): Fix formatting. (sparc_legitimize_pic_address): Minor tweaks. (sparc_delegitimize_address): Adjust assertion accordingly. * config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand into symbolic_operand. (movsi_high_pic_label_ref): Likewise. (movsi_lo_sum_pic_label_ref): Likewise. (movdi_pic_label_ref): Likewise. (movdi_high_pic_label_ref): Likewise. (movdi_lo_sum_pic_label_ref): Likewise. From-SVN: r259194 --- gcc/ChangeLog | 16 ++++++ gcc/config/sparc/sparc.c | 36 +++++++----- gcc/config/sparc/sparc.md | 12 ++-- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/opt/pr85196.C | 89 ++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr85196.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 08f7d51df50..f5273744037 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2018-04-06 Eric Botcazou + + PR target/85196 + * config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands + based on LABEL_REF. Remove useless assertion. + (pic_address_needs_scratch): Fix formatting. + (sparc_legitimize_pic_address): Minor tweaks. + (sparc_delegitimize_address): Adjust assertion accordingly. + * config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand + into symbolic_operand. + (movsi_high_pic_label_ref): Likewise. + (movsi_lo_sum_pic_label_ref): Likewise. + (movdi_pic_label_ref): Likewise. + (movdi_high_pic_label_ref): Likewise. + (movdi_lo_sum_pic_label_ref): Likewise. + 2018-04-06 Amaan Cheval * config.gcc (x86_64-*-rtems*): Add rtems.h to tm_file for diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 7126b57ba01..4026d4933d8 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -2236,7 +2236,7 @@ sparc_expand_move (machine_mode mode, rtx *operands) } } - /* Fixup TLS cases. */ + /* Fix up TLS cases. */ if (TARGET_HAVE_TLS && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) @@ -2245,15 +2245,20 @@ sparc_expand_move (machine_mode mode, rtx *operands) return false; } - /* Fixup PIC cases. */ + /* Fix up PIC cases. */ if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases. */ - if (GET_CODE (operands[1]) == LABEL_REF - && can_use_mov_pic_label_ref (operands[1])) + if ((GET_CODE (operands[1]) == LABEL_REF + && can_use_mov_pic_label_ref (operands[1])) + || (GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT + && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0)))) { if (mode == SImode) { @@ -2263,7 +2268,6 @@ sparc_expand_move (machine_mode mode, rtx *operands) if (mode == DImode) { - gcc_assert (TARGET_ARCH64); emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); return true; } @@ -4280,10 +4284,11 @@ int pic_address_needs_scratch (rtx x) { /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + && !SMALL_INT (XEXP (XEXP (x, 0), 1))) return 1; return 0; @@ -4750,16 +4755,15 @@ sparc_legitimize_tls_address (rtx addr) static rtx sparc_legitimize_pic_address (rtx orig, rtx reg) { - bool gotdata_op = false; - if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig))) { + bool gotdata_op = false; rtx pic_ref, address; rtx_insn *insn; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4770,8 +4774,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) /* If not during reload, allocate another temp reg here for loading in the address, so that these instructions can be optimized properly. */ - rtx temp_reg = (! can_create_pseudo_p () - ? reg : gen_reg_rtx (Pmode)); + rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg; /* Must put the SYMBOL_REF inside an UNSPEC here so that cse won't get confused into thinking that these two instructions @@ -4787,6 +4790,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) emit_insn (gen_movsi_high_pic (temp_reg, orig)); emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } + address = temp_reg; gotdata_op = true; } @@ -4827,7 +4831,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) && sparc_pic_register_p (XEXP (XEXP (orig, 0), 0))) return orig; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4935,7 +4939,11 @@ sparc_delegitimize_address (rtx x) && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL) { x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0); - gcc_assert (GET_CODE (x) == LABEL_REF); + gcc_assert (GET_CODE (x) == LABEL_REF + || (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)); } return x; diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 7988dece99d..df769405190 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1758,7 +1758,7 @@ (define_expand "movsi_pic_label_ref" [(set (match_dup 3) (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:SI (match_dup 3) (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1784,7 +1784,7 @@ (define_insn "*movsi_high_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI - (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 1 "symbolic_operand" "") (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1792,7 +1792,7 @@ (define_insn "*movsi_lo_sum_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") + (unspec:SI [(match_operand:SI 2 "symbolic_operand" "") (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") @@ -1896,7 +1896,7 @@ visl") (define_expand "movdi_pic_label_ref" [(set (match_dup 3) (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:DI (match_dup 3) (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) @@ -1922,7 +1922,7 @@ visl") (define_insn "*movdi_high_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI - (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 1 "symbolic_operand" "") (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0") @@ -1930,7 +1930,7 @@ visl") (define_insn "*movdi_lo_sum_pic_label_ref" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "") (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "TARGET_ARCH64 && flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e92ad3c241a..dad3874ff95 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-04-06 Eric Botcazou + + * g++.dg/opt/pr85196.C: New test. + 2018-04-06 David Malcolm PR c++/84269 diff --git a/gcc/testsuite/g++.dg/opt/pr85196.C b/gcc/testsuite/g++.dg/opt/pr85196.C new file mode 100644 index 00000000000..04d7abde4fa --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr85196.C @@ -0,0 +1,89 @@ +// PR target/85196 +// Testcase by Rainer Orth + +// { dg-do compile } +// { dg-options "-O -fpermissive -w" } +// { dg-additional-options "-fPIC" { target fpic } } + +class a; +template class b; +template class d : public b {}; +class e {}; +void f(int); +template class g { +public: + h(); + a i(); +}; +template <> class b : public g {}; +typedef (*j)(d); +template class l { +public: + k operator->() { return 0; } +}; +enum m { n, aa, o, ab, q, p }; +inline s(m ac) { + switch (ac) { + case n: + case aa: + case p: + return 1; + case o: + case ab: + return 2; + } +} +class D { + int ad; + +public: + *ae() { return &ad; } +}; +class a { + l af; + +public: + *r() { return af->ae(); } + t(int *c) { + int *w = af->ae(); + return w == c; + } +}; +class F : a { +public: + static int ah[]; + static e v(F *); + unsigned long ai() const; +}; +inline unsigned long F::ai() const { + m aj = r() - &ah[0]; + return s(aj); +} +inline e F::v(F *ak) { + long al = ak->ai(); + f(al); +} +template am() { return q; } +class an : F { +public: + static ao(d u) { + int *ap; + m aq = am(); + ap = &ah[aq]; + return u.h() && u.i().t(ap); + } + template static as() { + F at; + ar(&at); + } + template static au(int *, unsigned, e *) { + j av = ao; + d aw; + if (av(aw)) + as(); + } +}; +int *ax; +int ay; +e az; +ba() { an::au(ax, ay, &az); } -- 2.30.2