From 69bb37d577a023b80d1cbda86311a3dff40b2f7b Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 17 Jul 2019 00:47:25 +0300 Subject: [PATCH] package/gcc/9.1.0: fix ICE on ARC In a nutshell while compiling glibc GCC raises an Internal Compiler Error (ICE). This is a backport of upstream fix [1] for GCC's BUG #89838 [2]. The fix is the same as the one already merged for arc-2019.03 [3]. With the update of GCC to 9.2.0, this patch won't be needed anymore: it's already merged in both the stable "gcc-9-branch" branch and the "master" branch. [1] https://github.com/gcc-mirror/gcc/commit/472bac30e63ffacecfa5eda813054555f2cc7def [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89838 [3] https://git.buildroot.org/buildroot/commit/?h=dbf7fffb37e25c40fd5c03d0a64e50a1bba86424 Signed-off-by: Alexey Brodkin Cc: Thomas Petazzoni Cc: Evgeniy Didin Cc: Arnout Vandecappelle (Essensium/Mind) Signed-off-by: Thomas Petazzoni --- .../9.1.0/0001-ARC-Backport-fix-PR89838.patch | 367 ++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 package/gcc/9.1.0/0001-ARC-Backport-fix-PR89838.patch diff --git a/package/gcc/9.1.0/0001-ARC-Backport-fix-PR89838.patch b/package/gcc/9.1.0/0001-ARC-Backport-fix-PR89838.patch new file mode 100644 index 0000000000..3e8b86d709 --- /dev/null +++ b/package/gcc/9.1.0/0001-ARC-Backport-fix-PR89838.patch @@ -0,0 +1,367 @@ +From e5398fbcaa1dc35422958acfdb13074bf4a797a3 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Tue, 25 Jun 2019 11:02:21 +0000 +Subject: [PATCH 1/2] [ARC] Backport fix PR89838 + +Fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89838 +Similar to https://git.buildroot.org/buildroot/commit/?h=dbf7fffb37e25c40fd5c03d0a64e50a1bba86424 +but rebased on upstream stable "gcc-9-branch". + +gcc/ +xxxx-xx-xx Claudiu Zissulescu + + * config/arc/arc.c (arc_symbol_binds_local_p): New function. + (arc_legitimize_pic_address): Simplify and cleanup the function. + (SYMBOLIC_CONST): Remove. + (prepare_pic_move): Likewise. + (prepare_move_operands): Handle complex mov cases here. + (arc_legitimize_address_0): Remove call to + arc_legitimize_pic_address. + (arc_legitimize_address): Remove call to + arc_legitimize_tls_address. + * config/arc/arc.md (movqi_insn): Allow Cm3 match. + (movhi_insn): Likewise. + +/gcc/testsuite +xxxx-xx-xx Claudiu Zissulescu +Signed-off-by: Alexey Brodkin +--- + gcc/config/arc/arc.c | 238 ++++++++++++-------------------------------------- + gcc/config/arc/arc.md | 8 +- + 2 files changed, 60 insertions(+), 186 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 2f5753b02fa..daacc79d0cb 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -5971,130 +5971,47 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model) + } + } + +-/* Legitimize a pic address reference in ORIG. +- The return value is the legitimated address. +- If OLDX is non-zero, it is the target to assign the address to first. */ ++/* Return true if SYMBOL_REF X binds locally. */ + +-static rtx +-arc_legitimize_pic_address (rtx orig, rtx oldx) ++static bool ++arc_symbol_binds_local_p (const_rtx x) + { +- rtx addr = orig; +- rtx pat = orig; +- rtx base; ++ return (SYMBOL_REF_DECL (x) ++ ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) ++ : SYMBOL_REF_LOCAL_P (x)); ++} + +- if (oldx == orig) +- oldx = NULL; ++/* Legitimize a pic address reference in ADDR. The return value is ++ the legitimated address. */ + +- if (GET_CODE (addr) == LABEL_REF) +- ; /* Do nothing. */ +- else if (GET_CODE (addr) == SYMBOL_REF) ++static rtx ++arc_legitimize_pic_address (rtx addr) ++{ ++ if (!flag_pic) ++ return addr; ++ ++ switch (GET_CODE (addr)) + { +- enum tls_model model = SYMBOL_REF_TLS_MODEL (addr); +- if (model != 0) +- return arc_legitimize_tls_address (addr, model); +- else if (!flag_pic) +- return orig; +- else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr)) +- return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); ++ case SYMBOL_REF: ++ /* TLS symbols are handled in different place. */ ++ if (SYMBOL_REF_TLS_MODEL (addr)) ++ return addr; + + /* This symbol must be referenced via a load from the Global + Offset Table (@GOTPC). */ +- pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT); +- pat = gen_const_mem (Pmode, pat); +- +- if (oldx == NULL) +- oldx = gen_reg_rtx (Pmode); +- +- emit_move_insn (oldx, pat); +- pat = oldx; +- } +- else +- { +- if (GET_CODE (addr) == CONST) +- { +- addr = XEXP (addr, 0); +- if (GET_CODE (addr) == UNSPEC) +- { +- /* Check that the unspec is one of the ones we generate? */ +- return orig; +- } +- /* fwprop is placing in the REG_EQUIV notes constant pic +- unspecs expressions. Then, loop may use these notes for +- optimizations resulting in complex patterns that are not +- supported by the current implementation. The following +- two if-cases are simplifying the complex patters to +- simpler ones. */ +- else if (GET_CODE (addr) == MINUS) +- { +- rtx op0 = XEXP (addr, 0); +- rtx op1 = XEXP (addr, 1); +- gcc_assert (oldx); +- gcc_assert (GET_CODE (op1) == UNSPEC); +- +- emit_move_insn (oldx, +- gen_rtx_CONST (SImode, +- arc_legitimize_pic_address (op1, +- NULL_RTX))); +- emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx))); +- return oldx; +- +- } +- else if (GET_CODE (addr) != PLUS) +- { +- rtx tmp = XEXP (addr, 0); +- enum rtx_code code = GET_CODE (addr); +- +- /* It only works for UNARY operations. */ +- gcc_assert (UNARY_P (addr)); +- gcc_assert (GET_CODE (tmp) == UNSPEC); +- gcc_assert (oldx); +- +- emit_move_insn +- (oldx, +- gen_rtx_CONST (SImode, +- arc_legitimize_pic_address (tmp, +- NULL_RTX))); +- +- emit_insn (gen_rtx_SET (oldx, +- gen_rtx_fmt_ee (code, SImode, +- oldx, const0_rtx))); +- +- return oldx; +- } +- else +- { +- gcc_assert (GET_CODE (addr) == PLUS); +- if (GET_CODE (XEXP (addr, 0)) == UNSPEC) +- return orig; +- } +- } +- +- if (GET_CODE (addr) == PLUS) +- { +- rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1); ++ if (!arc_symbol_binds_local_p (addr)) ++ return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT)); + +- base = arc_legitimize_pic_address (op0, oldx); +- pat = arc_legitimize_pic_address (op1, +- base == oldx ? NULL_RTX : oldx); +- +- if (base == op0 && pat == op1) +- return orig; ++ /* Local symb: use @pcl to access it. */ ++ /* Fall through. */ ++ case LABEL_REF: ++ return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); + +- if (GET_CODE (pat) == CONST_INT) +- pat = plus_constant (Pmode, base, INTVAL (pat)); +- else +- { +- if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1))) +- { +- base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0)); +- pat = XEXP (pat, 1); +- } +- pat = gen_rtx_PLUS (Pmode, base, pat); +- } +- } ++ default: ++ break; + } + +- return pat; ++ return addr; + } + + /* Output address constant X to FILE, taking PIC into account. */ +@@ -6256,28 +6173,6 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) + } + } + +-#define SYMBOLIC_CONST(X) \ +-(GET_CODE (X) == SYMBOL_REF \ +- || GET_CODE (X) == LABEL_REF \ +- || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) +- +-/* Emit insns to move operands[1] into operands[0]. */ +- +-static void +-prepare_pic_move (rtx *operands, machine_mode) +-{ +- if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]) +- && flag_pic) +- operands[1] = force_reg (Pmode, operands[1]); +- else +- { +- rtx temp = (reload_in_progress ? operands[0] +- : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX); +- operands[1] = arc_legitimize_pic_address (operands[1], temp); +- } +-} +- +- + /* The function returning the number of words, at the beginning of an + argument, must be put in registers. The returned value must be + zero for arguments that are passed entirely in registers or that +@@ -9053,54 +8948,37 @@ prepare_move_operands (rtx *operands, machine_mode mode) + } + } + +- if (mode == SImode && SYMBOLIC_CONST (operands[1])) ++ if (GET_CODE (operands[1]) == SYMBOL_REF) + { +- prepare_pic_move (operands, SImode); +- +- /* Disable any REG_EQUALs associated with the symref +- otherwise the optimization pass undoes the work done +- here and references the variable directly. */ ++ enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]); ++ if (MEM_P (operands[0]) && flag_pic) ++ operands[1] = force_reg (mode, operands[1]); ++ else if (model) ++ operands[1] = arc_legitimize_tls_address (operands[1], model); + } + ++ operands[1] = arc_legitimize_pic_address (operands[1]); ++ ++ /* Store instructions are limited, they only accept as address an ++ immediate, a register or a register plus a small immediate. */ + if (MEM_P (operands[0]) +- && !(reload_in_progress || reload_completed)) ++ && !move_dest_operand (operands[0], mode)) + { +- operands[1] = force_reg (mode, operands[1]); +- if (!move_dest_operand (operands[0], mode)) +- { +- rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); +- /* This is like change_address_1 (operands[0], mode, 0, 1) , +- except that we can't use that function because it is static. */ +- rtx pat = change_address (operands[0], mode, addr); +- MEM_COPY_ATTRIBUTES (pat, operands[0]); +- operands[0] = pat; +- } +- if (!cse_not_expected) +- { +- rtx pat = XEXP (operands[0], 0); +- +- pat = arc_legitimize_address_0 (pat, pat, mode); +- if (pat) +- { +- pat = change_address (operands[0], mode, pat); +- MEM_COPY_ATTRIBUTES (pat, operands[0]); +- operands[0] = pat; +- } +- } ++ rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); ++ rtx tmp1 = change_address (operands[0], mode, tmp0); ++ MEM_COPY_ATTRIBUTES (tmp1, operands[0]); ++ operands[0] = tmp1; + } + +- if (MEM_P (operands[1]) && !cse_not_expected) +- { +- rtx pat = XEXP (operands[1], 0); +- +- pat = arc_legitimize_address_0 (pat, pat, mode); +- if (pat) +- { +- pat = change_address (operands[1], mode, pat); +- MEM_COPY_ATTRIBUTES (pat, operands[1]); +- operands[1] = pat; +- } +- } ++ /* Check if it is constant but it is not legitimized. */ ++ if (CONSTANT_P (operands[1]) ++ && !arc_legitimate_constant_p (mode, operands[1])) ++ operands[1] = force_reg (mode, XEXP (operands[1], 0)); ++ else if (MEM_P (operands[0]) ++ && ((CONSTANT_P (operands[1]) ++ && !satisfies_constraint_Cm3 (operands[1])) ++ || MEM_P (operands[1]))) ++ operands[1] = force_reg (mode, operands[1]); + + return false; + } +@@ -9572,11 +9450,10 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, + { + rtx addr, inner; + +- if (flag_pic && SYMBOLIC_CONST (x)) +- (x) = arc_legitimize_pic_address (x, 0); + addr = x; + if (GET_CODE (addr) == CONST) + addr = XEXP (addr, 0); ++ + if (GET_CODE (addr) == PLUS + && CONST_INT_P (XEXP (addr, 1)) + && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF +@@ -9607,13 +9484,6 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, + static rtx + arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode) + { +- if (GET_CODE (orig_x) == SYMBOL_REF) +- { +- enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x); +- if (model != 0) +- return arc_legitimize_tls_address (orig_x, model); +- } +- + rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode); + + if (new_x) +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index ce1004c1b56..78e304d4c71 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -671,7 +671,9 @@ core_3, archs4x, archs4xd, archs4xd_slow" + [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc") + (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))] + "register_operand (operands[0], QImode) +- || register_operand (operands[1], QImode)" ++ || register_operand (operands[1], QImode) ++ || (satisfies_constraint_Cm3 (operands[1]) ++ && memory_operand (operands[0], QImode))" + "@ + mov%? %0,%1%& + mov%? %0,%1%& +@@ -713,7 +715,9 @@ core_3, archs4x, archs4xd, archs4xd_slow" + /* Don't use a LIMM that we could load with a single insn - we loose + delay-slot filling opportunities. */ + && !satisfies_constraint_I (operands[1]) +- && satisfies_constraint_Usc (operands[0]))" ++ && satisfies_constraint_Usc (operands[0])) ++ || (satisfies_constraint_Cm3 (operands[1]) ++ && memory_operand (operands[0], HImode))" + "@ + mov%? %0,%1%& + mov%? %0,%1%& +-- +2.16.2 + -- 2.30.2