This is a regression present on the mainline and 7 branch: when the register
pressure is high, the use of DI/SI paradoxical subregs causes LRA to generate
invalid accesses to odd-numbered FP registers when registers are spilled.
The attached patch is aimed at drying up a big source of DI/SI paradoxical
subregs, namely 32-bit multiplication operations.
Tested on SPARC64/Linux, applied on mainline and 7 branch.
2017-09-08 Eric Botcazou <ebotca...@adacore.com>
PR target/81988
* config/sparc/sparc.md (mulsi3): Rename into *mulsi3_sp32.
(*mulsi3_sp64): New instruction.
(mulsi3): New expander.
2017-09-08 Eric Botcazou <ebotca...@adacore.com>
* gcc.dg/pr81988.c: New test.
--
Eric Botcazou
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md (revision 251861)
+++ config/sparc/sparc.md (working copy)
@@ -4517,7 +4517,14 @@ (define_insn "*cmp_ccv_minus_sltu_set"
;; The 32-bit multiply/divide instructions are deprecated on v9, but at
;; least in UltraSPARC I, II and IIi it is a win tick-wise.
-(define_insn "mulsi3"
+(define_expand "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "arith_operand" "")
+ (match_operand:SI 2 "arith_operand" "")))]
+ "TARGET_HARD_MUL || TARGET_ARCH64"
+ "")
+
+(define_insn "*mulsi3_sp32"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "arith_operand" "%r")
(match_operand:SI 2 "arith_operand" "rI")))]
@@ -4525,6 +4532,14 @@ (define_insn "mulsi3"
"smul\t%1, %2, %0"
[(set_attr "type" "imul")])
+(define_insn "*mulsi3_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "arith_operand" "%r")
+ (match_operand:SI 2 "arith_operand" "rI")))]
+ "TARGET_ARCH64"
+ "mulx\t%1, %2, %0"
+ [(set_attr "type" "imul")])
+
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (match_operand:DI 1 "arith_operand" "")
/* PR target/81988 */
/* Testcase by James Cowgill <jcowgill+...@jcowgill.uk> */
/* { dg-do assemble } */
/* { dg-require-effective-target pie } */
/* { dg-options "-O3 -fpie" } */
int c, d;
short **e;
int *a;
void foo(void)
{
int g[64 * 35], *h = g;
do {
short *f = e[d];
for (int i = 0; i < 4; i++)
a[i] = a[i] + (h[364] + f[4] * h[64] + f[5] * h[i] + f[6] * h[i + 3 * 4] +
f[7] * h[i + 4]);
} while (c);
}