From: Kyrylo Tkachov Date: Mon, 1 Oct 2018 12:39:43 +0000 (+0000) Subject: [arm] Avoid STRD with odd register for TARGET_ARM in output_move_double X-Git-Tag: releases/gcc-7.4.0~136 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a424211e585645c709cecb564a864ae4c4187a23;p=thirdparty%2Fgcc.git [arm] Avoid STRD with odd register for TARGET_ARM in output_move_double 2018-10-01 Kyrylo Tkachov Backport from mainline 2018-06-29 Kyrylo Tkachov * config/arm/arm.c (output_move_double): Don't allow STRD instructions if starting source register is not even. Backport from mainline 2018-07-02 Christophe Lyon * gcc.target/arm/arm-soft-strd-even.c: Skip if -mfloat-abi is overriden. 2018-06-29 Kyrylo Tkachov * gcc.target/arm/arm-soft-strd-even.c: New test. From-SVN: r264746 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 243391fe835e..5931c2641f2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-10-01 Kyrylo Tkachov + + Backport from mainline + 2018-06-29 Kyrylo Tkachov + + * config/arm/arm.c (output_move_double): Don't allow STRD instructions + if starting source register is not even. + 2018-09-29 Jakub Jelinek PR target/87467 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 886bcfa98b92..f0058a2722d2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -18187,12 +18187,18 @@ output_move_double (rtx *operands, bool emit, int *count) gcc_assert ((REGNO (operands[1]) != IP_REGNUM) || (TARGET_ARM && TARGET_LDRD)); + /* For TARGET_ARM the first source register of an STRD + must be even. This is usually the case for double-word + values but user assembly constraints can force an odd + starting register. */ + bool allow_strd = TARGET_LDRD + && !(TARGET_ARM && (REGNO (operands[1]) & 1) == 1); switch (GET_CODE (XEXP (operands[0], 0))) { case REG: if (emit) { - if (TARGET_LDRD) + if (allow_strd) output_asm_insn ("strd%?\t%1, [%m0]", operands); else output_asm_insn ("stm%?\t%m0, %M1", operands); @@ -18200,7 +18206,7 @@ output_move_double (rtx *operands, bool emit, int *count) break; case PRE_INC: - gcc_assert (TARGET_LDRD); + gcc_assert (allow_strd); if (emit) output_asm_insn ("strd%?\t%1, [%m0, #8]!", operands); break; @@ -18208,7 +18214,7 @@ output_move_double (rtx *operands, bool emit, int *count) case PRE_DEC: if (emit) { - if (TARGET_LDRD) + if (allow_strd) output_asm_insn ("strd%?\t%1, [%m0, #-8]!", operands); else output_asm_insn ("stmdb%?\t%m0!, %M1", operands); @@ -18218,7 +18224,7 @@ output_move_double (rtx *operands, bool emit, int *count) case POST_INC: if (emit) { - if (TARGET_LDRD) + if (allow_strd) output_asm_insn ("strd%?\t%1, [%m0], #8", operands); else output_asm_insn ("stm%?\t%m0!, %M1", operands); @@ -18226,7 +18232,7 @@ output_move_double (rtx *operands, bool emit, int *count) break; case POST_DEC: - gcc_assert (TARGET_LDRD); + gcc_assert (allow_strd); if (emit) output_asm_insn ("strd%?\t%1, [%m0], #-8", operands); break; @@ -18237,8 +18243,8 @@ output_move_double (rtx *operands, bool emit, int *count) otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0); otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1); - /* IWMMXT allows offsets larger than ldrd can handle, - fix these up with a pair of ldr. */ + /* IWMMXT allows offsets larger than strd can handle, + fix these up with a pair of str. */ if (!TARGET_THUMB2 && CONST_INT_P (otherops[2]) && (INTVAL(otherops[2]) <= -256 @@ -18303,7 +18309,7 @@ output_move_double (rtx *operands, bool emit, int *count) return ""; } } - if (TARGET_LDRD + if (allow_strd && (REG_P (otherops[2]) || TARGET_THUMB2 || (CONST_INT_P (otherops[2]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d7c87183e3e7..92e8f439cf22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2018-10-01 Kyrylo Tkachov + + Backport from mainline + 2018-07-02 Christophe Lyon + + * gcc.target/arm/arm-soft-strd-even.c: Skip if -mfloat-abi is + overriden. + 2018-06-29 Kyrylo Tkachov + + * gcc.target/arm/arm-soft-strd-even.c: New test. + 2018-09-29 Jakub Jelinek PR target/87467 diff --git a/gcc/testsuite/gcc.target/arm/arm-soft-strd-even.c b/gcc/testsuite/gcc.target/arm/arm-soft-strd-even.c new file mode 100644 index 000000000000..4ef3dd8be392 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/arm-soft-strd-even.c @@ -0,0 +1,19 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_arm_ok } */ +/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } {"-mfloat-abi=soft" } } */ +/* { dg-options "-O2 -marm -mfloat-abi=soft" } */ + +/* Check that we don't try to emit STRD in ARM state with + odd starting register. */ + +struct S { + double M0; +} __attribute((aligned)) __attribute((packed)); + +void bar(void *); + +void foo(int x, struct S y) { + asm("" : : : "r1", "r8", "r7", "r4"); + y.M0 ?: bar(0); + bar(__builtin_alloca(8)); +}