Hi all, The testcase in this patch generates bogus assembly for arm with -O1 -mfloat-abi=soft: strd r4, [#0, r3]
This is due to non-canonical RTL being generated during expansion: (set (mem:DI (plus:SI (const_int 0 [0]) (reg/f:SI 153)) [0 MEM[symbol: a, index: _26, offset: 0B]+0 S8 A64]) (reg:DI 154)) Note the (plus (const_int 0) (reg)). This is being generated in gen_addr_rtx in tree-ssa-address.c where it creates an explicit PLUS rtx through gen_rtx_PLUS, which doesn't try to canonicalise its arguments or simplify. The correct thing to do is to use simplify_gen_binary that will handle all this properly. I didn't change the other gen_rtx_PLUS calls in this function as their results is later used in XEXP operations that seem to rely on a PLUS expression being explicitly produced, but this particular call doesn't, so it's okay to change it. With this patch the sane assembly is generated: strd r4, [r3] Bootstrapped and tested on arm-none-linux-gnueabihf, x86_64, aarch64-none-linux-gnu. Ok for trunk? Thanks, Kyrill 2016-12-20 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * tree-ssa-address.c (gen_addr_rtx): Use simplify_gen_binary to add *addr to act_elem. 2016-12-20 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * gcc.dg/20161219.c: New test.
diff --git a/gcc/testsuite/gcc.dg/20161219.c b/gcc/testsuite/gcc.dg/20161219.c new file mode 100644 index 0000000000000000000000000000000000000000..93ea8d2364d9ab54704a84e6c0bff0427df82db8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20161219.c @@ -0,0 +1,30 @@ +/* { dg-do assemble } */ +/* { dg-options "-O1 -w" } */ + +static long long a[9]; +int b, c, d, e, g; + +static int +fn1 (int *p1) +{ + b = 1; + for (; b >= 0; b--) + { + d = 0; + for (;; d++) + { + e && (a[d] = 0); + if (*p1) + break; + c = (int) a; + } + } + return 0; +} + +int +main () +{ + int f = fn1 ((int *) f); + return f; +} diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index a53ade0600d01c9d48f6c789b78fd42d7a06a95b..0c7c5902cebb0196c8e27f4eba45ce176cc3f0a5 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -154,7 +154,7 @@ gen_addr_rtx (machine_mode address_mode, } if (*addr) - *addr = gen_rtx_PLUS (address_mode, *addr, act_elem); + *addr = simplify_gen_binary (PLUS, address_mode, *addr, act_elem); else *addr = act_elem; }