Some insns, which operate on SImode operands, output assembler template
that comprise of multiple instructions using HImode operands. To access
the high word of an SImode operand, an operand selector '%H' is used to
offset the operand value by a constant amount.

When one of these HImode operands is a memory reference to a post_inc,
the address does not need to be offset, since the preceding instruction
has already offset the address to the correct value.

This fixes an ICE in change_address_1, at emit-rtl.c:2318 for
gcc.c-torture/execute/pr20527-1.c in the "-mlarge -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects" configuration.

This test generated the following insn, and the attempt to output the
high part of the post_inc address caused the ICE.
(set (reg:SI 6 R6)
     (minus:SI (reg:SI 6 R6)
               (mem:SI (post_inc:PSI (reg:PSI 10 R10)) {subsi3}

Committed the attached patch as obvious.
>From 04637536a6b69c6bf7e22e2ccd5ff3bfc4892394 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <joze...@mittosystems.com>
Date: Fri, 10 Apr 2020 17:31:33 +0100
Subject: [PATCH] MSP430: Dont add offsets to addresses when emitting asm for
 post_inc

Some insns, which operate on SImode operands, output assembler template
that comprise of multiple instructions using HImode operands. To access
the high word of an SImode operand, an operand selector '%H' is used to
offset the operand value by a constant amount.

When one of these HImode operands is a memory reference to a post_inc,
the address does not need to be offset, since the preceding instruction
has already offset the address to the correct value.

This fixes an ICE in change_address_1, at emit-rtl.c:2318 for
gcc.c-torture/execute/pr20527-1.c in the "-mlarge -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects" configuration.

This test generated the following insn, and the attempt to output the
high part of the post_inc address caused the ICE.
(set (reg:SI 6 R6)
     (minus:SI (reg:SI 6 R6)
               (mem:SI (post_inc:PSI (reg:PSI 10 R10)) {subsi3}

gcc/ChangeLog:

2020-04-13  Jozef Lawrynowicz  <joze...@mittosystems.com>

	* config/msp430/msp430.c (msp430_print_operand): Don't add offsets to
	memory references in %B, %C and %D operand selectors when the inner
	operand is a post increment address.
---
 gcc/ChangeLog              |  6 ++++++
 gcc/config/msp430/msp430.c | 10 +++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c0ac32dccf6..8bfc2127989 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-04-13  Jozef Lawrynowicz  <joze...@mittosystems.com>
+
+	* config/msp430/msp430.c (msp430_print_operand): Don't add offsets to
+	memory references in %B, %C and %D operand selectors when the inner
+	operand is a post increment address.
+
 2020-04-13  Jozef Lawrynowicz  <joze...@mittosystems.com>
 
 	* config/msp430/msp430.c (msp430_print_operand): Offset a %C memory
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 96532740ac1..e77ca101599 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -3474,7 +3474,9 @@ msp430_print_operand (FILE * file, rtx op, int letter)
       switch (GET_CODE (op))
 	{
 	case MEM:
-	  op = adjust_address (op, Pmode, 2);
+	  /* We don't need to adjust the address for post_inc.  */
+	  op = adjust_address (op, Pmode,
+			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 2);
 	  break;
 	case REG:
 	  op = gen_rtx_REG (Pmode, REGNO (op) + 1);
@@ -3492,7 +3494,8 @@ msp430_print_operand (FILE * file, rtx op, int letter)
       switch (GET_CODE (op))
 	{
 	case MEM:
-	  op = adjust_address (op, Pmode, 4);
+	  op = adjust_address (op, Pmode,
+			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 4);
 	  break;
 	case REG:
 	  op = gen_rtx_REG (Pmode, REGNO (op) + 2);
@@ -3510,7 +3513,8 @@ msp430_print_operand (FILE * file, rtx op, int letter)
       switch (GET_CODE (op))
 	{
 	case MEM:
-	  op = adjust_address (op, Pmode, 6);
+	  op = adjust_address (op, Pmode,
+			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 6);
 	  break;
 	case REG:
 	  op = gen_rtx_REG (Pmode, REGNO (op) + 3);
-- 
2.17.1

Reply via email to