diff mbox

[AArch64] Add register constraints to add<mode>3_pluslong

Message ID 1449258149-4266-1-git-send-email-james.greenhalgh@arm.com
State New
Headers show

Commit Message

James Greenhalgh Dec. 4, 2015, 7:42 p.m. UTC
Hi,

This patch fixes a bug I spotted in the add<mode>3_pluslong insn_and_split
pattern. We need to give register constraints, otherwise the register
allocator can do whatever it likes. This manifests as an ICE on AArch64
with -mabi=ilp32:

gcc foo.c -O2 -mabi=ilp32

  error: could not split insn
   }
   ^

  (insn:TI 85 95 7 (set (mem/c:DI (plus:DI (reg/f:DI 29 x29)
                  (const_int 40 [0x28])) [1 %sfp+-65528 S8 A64])
          (plus:DI (plus:DI (reg/f:DI 29 x29)
                  (const_int 16 [0x10]))
              (const_int 65552 [0x10010]))) foo.c:7 95 {*adddi3_pluslong}
       (nil))

The patch simply constrains the pattern to use w/x registers.

Bootstrapped on aarch64-none-linux-gnu and cross-tested on aarch64-none-elf
with no issues.

OK?

Thanks,
James

---
gcc/

2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>

	* config/aarch64/aarch64.md (add<mode>3_pluslong): Add register
	constraints.

gcc/testsuite/

2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>

	* gcc.c-torture/compile/20151204.c: New.

Comments

Marcus Shawcroft Dec. 4, 2015, 7:45 p.m. UTC | #1
On 4 December 2015 at 19:42, James Greenhalgh <james.greenhalgh@arm.com> wrote:
>

> Hi,

>

> This patch fixes a bug I spotted in the add<mode>3_pluslong insn_and_split

> pattern. We need to give register constraints, otherwise the register

> allocator can do whatever it likes. This manifests as an ICE on AArch64

> with -mabi=ilp32:

>

> gcc foo.c -O2 -mabi=ilp32

>

>   error: could not split insn

>    }

>    ^

>

>   (insn:TI 85 95 7 (set (mem/c:DI (plus:DI (reg/f:DI 29 x29)

>                   (const_int 40 [0x28])) [1 %sfp+-65528 S8 A64])

>           (plus:DI (plus:DI (reg/f:DI 29 x29)

>                   (const_int 16 [0x10]))

>               (const_int 65552 [0x10010]))) foo.c:7 95 {*adddi3_pluslong}

>        (nil))

>

> The patch simply constrains the pattern to use w/x registers.

>

> Bootstrapped on aarch64-none-linux-gnu and cross-tested on aarch64-none-elf

> with no issues.

>

> OK?

>

> Thanks,

> James

>

> ---

> gcc/

>

> 2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>

>

>         * config/aarch64/aarch64.md (add<mode>3_pluslong): Add register

>         constraints.

>

> gcc/testsuite/

>

> 2015-12-04  James Greenhalgh  <james.greenhalgh@arm.com>

>

>         * gcc.c-torture/compile/20151204.c: New.

>


+main(int argc, char** argv)

Space before (.

OK
/M
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 765df6a..79d1414 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1613,9 +1613,9 @@ 
 
 (define_insn_and_split "*add<mode>3_pluslong"
   [(set
-    (match_operand:GPI 0 "register_operand" "")
-    (plus:GPI (match_operand:GPI 1 "register_operand" "")
-	      (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
+    (match_operand:GPI 0 "register_operand" "=r")
+    (plus:GPI (match_operand:GPI 1 "register_operand" "r")
+	      (match_operand:GPI 2 "aarch64_pluslong_immediate" "i")))]
   "!aarch64_plus_operand (operands[2], VOIDmode)
    && !aarch64_move_imm (INTVAL (operands[2]), <MODE>mode)"
   "#"
diff --git a/gcc/testsuite/gcc.c-torture/compile/20151204.c b/gcc/testsuite/gcc.c-torture/compile/20151204.c
new file mode 100644
index 0000000..4a05671
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20151204.c
@@ -0,0 +1,19 @@ 
+typedef __SIZE_TYPE__ size_t;
+
+int strcmp (const char*, const char*);
+void *memchr (const void *, int, size_t);
+char* strncpy (char *, const char *, size_t);
+
+int
+main(int argc, char** argv)
+{
+  char target[32753] = "A";
+  char buffer[32753];
+  char *x;
+  x = buffer;
+
+  if (strcmp (target, "A")
+      || memchr (target, 'A', 0) != ((void *) 0))
+    if (strncpy (x, "", 4) != x);
+  return 0;
+}