Commit 69128a17 by Eric Botcazou Committed by Eric Botcazou

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
parent 5f690e68
2018-04-06 Eric Botcazou <ebotcazou@adacore.com>
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 <amaan.cheval@gmail.com>
* config.gcc (x86_64-*-rtems*): Add rtems.h to tm_file for
......
......@@ -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;
......
......@@ -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")
......
2018-04-06 Eric Botcazou <ebotcazou@adacore.com>
* g++.dg/opt/pr85196.C: New test.
2018-04-06 David Malcolm <dmalcolm@redhat.com>
PR c++/84269
......
// PR target/85196
// Testcase by Rainer Orth <ro@gcc.gnu.org>
// { dg-do compile }
// { dg-options "-O -fpermissive -w" }
// { dg-additional-options "-fPIC" { target fpic } }
class a;
template <typename> class b;
template <typename k> class d : public b<k> {};
class e {};
void f(int);
template <class> class g {
public:
h();
a i();
};
template <> class b<e> : public g<e> {};
typedef (*j)(d<e>);
template <class k> 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<D *> 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 <typename> am() { return q; }
class an : F {
public:
static ao(d<e> u) {
int *ap;
m aq = am<unsigned>();
ap = &ah[aq];
return u.h() && u.i().t(ap);
}
template <e ar(F *)> static as() {
F at;
ar(&at);
}
template <e ar(F *)> static au(int *, unsigned, e *) {
j av = ao;
d<e> aw;
if (av(aw))
as<ar>();
}
};
int *ax;
int ay;
e az;
ba() { an::au<an::v>(ax, ay, &az); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment