This patch eliminates a check of targetm.truly_noop_truncation from the early middle-end, where the gimple/generic being generated by GCC's front-ends is being inappropriately influenced by the target's TRULY_NOOP_TRUNCATION. The (recent) intention of TRULY_NOOP_TRUNCATION is to indicate that a backend requires explicit truncation instructions rather than using SUBREGs to perform truncations. A long standing (and probably unintentional) side-effect has been that this setting also controls whether the middle-end narrows integer operations at the tree-level. Understandably, GCC and its testsuite assume that GIMPLE and GENERIC behave consistently across platforms, and alas defining TRULY_NOOP_TRUNCATION away from the default triggers several regressions (including gcc.dg/fold-rotate-1.c).
Hopefully, I can appeal to a design philosophy argument that the early middle-end (tree-ssa) passes should be as machine independent as possible, and target settings influence the late middle-end (RTL) passes. Most of the backend hooks were eliminated from "fold" and the tree code with GCC 4.x, but perhaps TRULY_NOOP_TRUNCATION appears to have survived, probably because it is so rarely used. It's only defined by three (current) backends: gcn, mips and tilegx. Everywhere else TRULY_NOOP_TRUNCATION is unconditionally true, so that convert_to_integer_1 always calls do_narrow. This check of TRULY_NOOP_TRUNCATION (in convert_to_integer) dates back to (before) gcc 0.9 in 1987. Mysteriously, at that point in time, all targets defined TRULY_NOOP_TRUNCATION to 1, so perhaps only Richard Stallman remembers why this code was ever added to the compiler. Even if truncations require explicit instructions, that shouldn't prevent the compiler from generating them (or using narrow integer operations). The following patch has been tested on x86_64-pc-linux-gnu with no regressions (where of course you wouldn't expect any changes), and on a x86_64-pc-linux-gnu that defines TRULY_NOOP_TRUNCATION to false, where it cures 17 of the regressions that are introduced. It also fixes all of the regressions introduced by defining TRULY_NOOP_TRUNCATION to false on nvptx-none. I had hoped to also test on a MIPS target, but after over 10 days of bootstrap builds on the GCC compile farm, gcc23.fsffrance.org has started experiencing hardware issues (overheating?), so it may be a while before I can fully confirm this change causes no problems (and potentially fixes a few) on MIPS. Ok for mainline? 2020-07-11 Roger Sayle <ro...@nextmovesoftware.com> gcc/ChangeLog * convert.c (convert_to_integer_1): Narrow integer operations even on targets that require explicit truncation instructions. Thanks in advance, Roger -- Roger Sayle NextMove Software Cambridge, UK
diff --git a/gcc/convert.c b/gcc/convert.c index 42509c5..292c513 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -836,16 +836,10 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0)))) break; - if (outprec >= BITS_PER_WORD - || targetm.truly_noop_truncation (outprec, inprec) - || inprec > TYPE_PRECISION (TREE_TYPE (arg0)) - || inprec > TYPE_PRECISION (TREE_TYPE (arg1))) - { - tree tem = do_narrow (loc, ex_form, type, arg0, arg1, - expr, inprec, outprec, dofold); - if (tem) - return tem; - } + tree tem = do_narrow (loc, ex_form, type, arg0, arg1, + expr, inprec, outprec, dofold); + if (tem) + return tem; } break;