From: Eric Botcazou Date: Fri, 6 Apr 2018 22:33:55 +0000 (+0000) Subject: re PR middle-end/85196 (ICE in extract_insn, at recog.c:2311: unrecognizable insn) X-Git-Tag: releases/gcc-6.5.0~397 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dd85d69ed7c4c4cec950526e1289ff2b3b12ec0;p=thirdparty%2Fgcc.git 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: r259196 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeaee798e9ca..2186cef8198e 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-05 Uros Bizjak PR target/85193 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index f4c9b4084e61..1cec1d7370f0 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1837,7 +1837,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])) @@ -1846,15 +1846,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) { @@ -1864,7 +1869,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; } @@ -3851,10 +3855,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; @@ -4295,16 +4300,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); @@ -4315,8 +4319,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 @@ -4332,6 +4335,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; } @@ -4372,7 +4376,7 @@ sparc_legitimize_pic_address (rtx orig, rtx reg) && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) return orig; - if (reg == 0) + if (!reg) { gcc_assert (can_create_pseudo_p ()); reg = gen_reg_rtx (Pmode); @@ -4481,7 +4485,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 cae6547bab76..34d01b49a623 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -1525,7 +1525,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))) @@ -1551,7 +1551,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") @@ -1559,7 +1559,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") @@ -1661,7 +1661,7 @@ (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))) @@ -1687,7 +1687,7 @@ (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") @@ -1695,7 +1695,7 @@ (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 b9988f541a23..4101bf9e3b07 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-05 Uros Bizjak PR target/85193 diff --git a/gcc/testsuite/g++.dg/opt/pr85196.C b/gcc/testsuite/g++.dg/opt/pr85196.C new file mode 100644 index 000000000000..04d7abde4fa7 --- /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); }