From 01e83a10874735bcf65fc01671b40f70342074d5 Mon Sep 17 00:00:00 2001 From: Matthew Beliveau Date: Tue, 23 Jul 2019 15:56:22 +0000 Subject: [PATCH] re PR rtl-optimization/91173 (ICE: in int_mode_for_mode, at stor-layout.c:403) PR rtl-optimization/91173 Backported from mainline 2019-07-16 Jeff Law PR rtl-optimization/91173 * tree-ssa-address.c (addr_for_mem_ref): If the base is an SSA_NAME with a constant value, fold its value into the offset and clear the base before calling gen_addr_rtx. * g++.dg/pr91173.C: New test. From-SVN: r273741 --- gcc/ChangeLog | 11 +++++++++ gcc/testsuite/g++.dg/pr91173.C | 45 ++++++++++++++++++++++++++++++++++ gcc/tree-ssa-address.c | 14 +++++++++++ 3 files changed, 70 insertions(+) create mode 100644 gcc/testsuite/g++.dg/pr91173.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b480c19dba47..cf38fd1f5128 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-07-23 Matthew Beliveau + + Backported from mainline + 2019-07-16 Jeff Law + + PR rtl-optimization/91173 + * tree-ssa-address.c (addr_for_mem_ref): If the base is an + SSA_NAME with a constant value, fold its value into the offset + and clear the base before calling gen_addr_rtx. + * g++.dg/pr91173.C: New test. + 2019-07-23 Richard Biener PR debug/91231 diff --git a/gcc/testsuite/g++.dg/pr91173.C b/gcc/testsuite/g++.dg/pr91173.C new file mode 100644 index 000000000000..b8fb41ba0cdc --- /dev/null +++ b/gcc/testsuite/g++.dg/pr91173.C @@ -0,0 +1,45 @@ +class a { + int b; + void *c; + +public: + bool aa(); + int &ab() { + if (aa()) { + void *d(c); + return static_cast(d)[b]; + } + return *(int *)0; + } +}; +typedef enum {E} e; +class f : public a { + int g; + +public: + int ac() { + if (g) + return 1; + return ac(); + } +}; +int *ad; +struct h { + static int ae(e, int *m) { + f ag; + int *ah; + while (!0) { + ad = &ag.ab(); + ah = ad + ag.ac(); + while (ad < ah) + *m = *ad++; + } + } +}; +template +void i(int *, int *, int, int *, e n, int *o) { + h::ae(n, o); +} +int aq, ar, as, at, au; +void aw() { i(&aq, &ar, as, &at, (e)0, &au); } + diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index 1c17e935914d..2e5d87734d65 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -259,6 +259,20 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, ? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL) : NULL_RTX); + /* addr->base could be an SSA_NAME that was set to a constant value. The + call to expand_expr may expose that constant. If so, fold the value + into OFF and clear BSE. Otherwise we may later try to pull a mode from + BSE to generate a REG, which won't work with constants because they + are modeless. */ + if (bse && GET_CODE (bse) == CONST_INT) + { + if (off) + off = simplify_gen_binary (PLUS, pointer_mode, bse, off); + else + off = bse; + gcc_assert (GET_CODE (off) == CONST_INT); + bse = NULL_RTX; + } gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL); if (pointer_mode != address_mode) address = convert_memory_address (address_mode, address); -- 2.47.2