Bug 59695 - bad code generation on aarch64 in aarch64_output_mi_thunk
Summary: bad code generation on aarch64 in aarch64_output_mi_thunk
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.3
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-01-06 09:51 UTC by Matthias Klose
Modified: 2014-02-07 10:44 UTC (History)
1 user (show)

See Also:
Host:
Target: aarch64-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Klose 2014-01-06 09:51:25 UTC
seen in a segfault running the tests in the coinor-osi package,
https://launchpad.net/bugs/1263576, both in saucy and trusty, version 0.106.4
and 0.106.5. Version 0.103 doesn't show the issue.

both the 4.7 and 4.8 linaro branches show this behaviour, and trunk 20131121
(didn't build a newer one yet).

William Grant tracked that down to a bug with very negative vcall_offsets in
aarch64 multiple inheritance thunks. The example below has two consecutive
thunks, with the second adding 263 instead of subtracting 264.
aarch64_build_constant seems to not handle negative integers. He tried a quick
gcc patch to avoid using aarch64_build_constant, and the coinor-osi tests succeed.

0000000000401ca4 <_ZTv0_n256_N1C2adEv>:
  401ca4:       f9400010        ldr     x16, [x0]
  401ca8:       f8500211        ldr     x17, [x16,#-256]
  401cac:       8b110000        add     x0, x0, x17
  401cb0:       17fffff9        b       401c94 <_ZN1C2adEv>

[...]

0000000000401cc4 <_ZTv0_n264_N1C2aeEv>:
  401cc4:       f9400010        ldr     x16, [x0]
  401cc8:       d28020f1        mov     x17, #0x107                     // #263
  401ccc:       f8716a11        ldr     x17, [x16,x17]
  401cd0:       8b110000        add     x0, x0, x17
  401cd4:       17fffff8        b       401cb4 <_ZN1C2aeEv>

Any chance for a quick 2013 review?

Thanks, Matthias

--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2540,8 +2540,8 @@
 	  addr = plus_constant (Pmode, temp0, vcall_offset);
       else
 	{
-	  aarch64_build_constant (IP1_REGNUM, vcall_offset);
-	  addr = gen_rtx_PLUS (Pmode, temp0, temp1);
+	  aarch64_add_constant (IP0_REGNUM, IP1_REGNUM, vcall_offset);
+	  addr = temp0;
 	}

       aarch64_emit_move (temp1, gen_rtx_MEM (Pmode,addr));
Comment 1 mgretton 2014-01-09 13:50:42 UTC
I think the actual issue is with the code in aarch64_build_constant:

      /* zcount contains the number of additional MOVK instructions
	 required if the constant is built up with an initial MOVZ instruction,
	 while ncount is the number of MOVK instructions required if starting
	 with a MOVN instruction.  Choose the sequence that yields the fewest
	 number of instructions, preferring MOVZ instructions when they are both
	 the same.  */
      if (ncount < zcount)
	{
	  emit_move_insn (gen_rtx_REG (Pmode, regnum),
			  GEN_INT ((~val) & 0xffff));
	  tval = 0xffff;
	}
      else
	{
	  emit_move_insn (gen_rtx_REG (Pmode, regnum),
			  GEN_INT (val & 0xffff));
	  tval = 0;
	}

The GEN_INT in the first if branch is incorrect as it truncates the immediate at 16-bits, and so we will never generate the "MOVN" form.  What it should be instead is: GEN_INT (~((~val) & 0xffff)) or equivalent.
Comment 2 Christophe Lyon 2014-01-15 10:28:27 UTC
Author: clyon
Date: Wed Jan 15 10:27:55 2014
New Revision: 206628

URL: http://gcc.gnu.org/viewcvs?rev=206628&root=gcc&view=rev
Log:
2014-01-15  Matthew Gretton-Dann  <matthew.gretton-dann@linaro.org>
            Kugan Vivekanandarajah  <kuganv@linaro.org>

	gcc/
	PR target/59695
	* config/aarch64/aarch64.c (aarch64_build_constant): Fix incorrect
	truncation.

	gcc/testsuite/
	PR target/59695
	* g++.dg/pr59695.C: New testcase.


Added:
    trunk/gcc/testsuite/g++.dg/pr59695.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/aarch64/aarch64.c
    trunk/gcc/testsuite/ChangeLog
Comment 3 Christophe Lyon 2014-01-17 11:05:36 UTC
Author: clyon
Date: Fri Jan 17 11:05:04 2014
New Revision: 206703

URL: http://gcc.gnu.org/viewcvs?rev=206703&root=gcc&view=rev
Log:
2014-01-17  Kugan Vivekanandarajah  <kuganv@linaro.org>

	gcc/
	Backport from mainline
	2014-01-15  Matthew Gretton-Dann  <matthew.gretton-dann@linaro.org>
            Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR target/59695
	* config/aarch64/aarch64.c (aarch64_build_constant): Fix incorrect
	truncation.

	gcc/testsuite/
	Backport from mainline
	2014-01-15  Matthew Gretton-Dann  <matthew.gretton-dann@linaro.org>
	    Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR target/59695
	* g++.dg/pr59695.C: New testcase.


Added:
    branches/gcc-4_8-branch/gcc/testsuite/g++.dg/pr59695.C
      - copied unchanged from r206628, trunk/gcc/testsuite/g++.dg/pr59695.C
Modified:
    branches/gcc-4_8-branch/   (props changed)
    branches/gcc-4_8-branch/gcc/ChangeLog
    branches/gcc-4_8-branch/gcc/config/aarch64/aarch64.c
    branches/gcc-4_8-branch/gcc/testsuite/ChangeLog

Propchange: branches/gcc-4_8-branch/
            ('svn:mergeinfo' modified)
Comment 4 Ramana Radhakrishnan 2014-02-07 10:44:34 UTC
Fixed now presumably.