Hi all, I notice that the output code for our store exclusive patterns accesses unallocated memory. It wants to output an strexd instruction with a pair of consecutive registers corresponding to a DImode value. For that it creates the SImode top half of the DImode register and puts it into operands[3]. But the pattern only defines entries only up to operands[2], with no match_dup 3 or like that, so operands[3] should technically be out of bounds.
We already have a mechanism for printing the top half of a DImode register, that's the 'H' output modifier. So this patch changes those patterns to use that, eliminating the out of bounds access and making the code a bit simpler as well. Bootstrapped and tested on arm-none-linux-gnueabihf. Ok for trunk? Thanks, Kyrill 2016-03-09 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * config/arm/sync.md (arm_store_exclusive<mode>): Use 'H' output modifier on operands[2] rather than creating a new entry in out-of-bounds memory of the operands array. (arm_store_release_exclusivedi): Likewise.
diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md index 6dd2dc396210bc45374d13e1a20f124cc490b630..8158f53025400045569533a1e8c6583025d490c8 100644 --- a/gcc/config/arm/sync.md +++ b/gcc/config/arm/sync.md @@ -422,14 +422,13 @@ (define_insn "arm_store_exclusive<mode>" { if (<MODE>mode == DImode) { - rtx value = operands[2]; /* The restrictions on target registers in ARM mode are that the two registers are consecutive and the first one is even; Thumb is actually more flexible, but DI should give us this anyway. - Note that the 1st register always gets the lowest word in memory. */ - gcc_assert ((REGNO (value) & 1) == 0 || TARGET_THUMB2); - operands[3] = gen_rtx_REG (SImode, REGNO (value) + 1); - return "strexd%?\t%0, %2, %3, %C1"; + Note that the 1st register always gets the + lowest word in memory. */ + gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2); + return "strexd%?\t%0, %2, %H2, %C1"; } return "strex<sync_sfx>%?\t%0, %2, %C1"; } @@ -445,11 +444,9 @@ (define_insn "arm_store_release_exclusivedi" VUNSPEC_SLX))] "TARGET_HAVE_LDACQ && ARM_DOUBLEWORD_ALIGN" { - rtx value = operands[2]; /* See comment in arm_store_exclusive<mode> above. */ - gcc_assert ((REGNO (value) & 1) == 0 || TARGET_THUMB2); - operands[3] = gen_rtx_REG (SImode, REGNO (value) + 1); - return "stlexd%?\t%0, %2, %3, %C1"; + gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2); + return "stlexd%?\t%0, %2, %H2, %C1"; } [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")])