[Bug rtl-optimization/49034] New: ARM optimizer generating incorrect code (causing bad pointer dereference)

2011-05-17 Thread michaelatnavman at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49034

   Summary: ARM optimizer generating incorrect code (causing bad
pointer dereference)
   Product: gcc
   Version: 4.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: michaelatnav...@gmail.com
  Host: darwin-x86
Target: arm-eabi
 Build: 4.4.0 (android NDK r5b)


The ARM optimizer appears to sometimes forget that a register has been
overwritten. This especially causes a problem when it uses an overwritten
register to do a memory access.

The general C++ code structure is:
  struct TPointInt
  {
int x;
int y;

TPointInt (int iX, int iY)
: x(iX), y(iY) { }

TPointInt operator-(const TPointInt &rhs) const
{
  return TPointInt(x - rhs.x, y - rhs.y);
}
  };

  class LineEndPoints
  {
public:
  TPointInt p0;
  TPointInt p1;
  };

  class Line
  {
public:
  LineEndPoints mEndPoints;
  int mLength;
  };

  void bar(Line *const lineBuffer, int &nLinesCnt)
  {
// ...
Line &curLine = lineBuffer[nLinesCnt];
const TPointInt lineVec = curLine.mEndPoints.p1 -
  curLine.mEndPoints.p0; // 
// ...
  }

  void foo(void)
  {
static Line lineBuffer[40];
int nLinesCnt = 0;
bar(lineBuffer);
  }

The line indicated with "" essentially does:
  lineVec.x = curLine.mEndPoints.p1.x - curLine.mEndPoints.p0.x;
  lineVec.y = curLine.mEndPoints.p1.y - curLine.mEndPoints.p0.y;

The assembler output is:
  ; 0x83a0083a is a branch target from a single location. It does not fall
  ; through from 0x83a00838. Prior to the branch, r0 is set to contain the
  ; address of curLine.
  0x83a0083a :  ldr r2, [r0, #8]   ; Get curLine.mEndPoints.p1.x
  0x83a0083c :  ldr r0, [r0, #0]   ; Get curLine.mEndPoints.p0.x
  0x83a0083e :  subsr2, r2, r0 ; Subtract
  0x83a00840 :  str r2, [sp, #44]  ; Store the x result
  0x83a00842 :  ldr r2, [r0, #4]   ; Get curLine.mEndPoints.p1.y
; except r0 has been
overwritten
; above!
  0x83a00844 :  ldr r1, [r0, #12]  ; Get curLine.mEndPoints.p0.y
  0x83a00846 :  subsr1, r1, r2 ; Subtract
  0x83a00848 :  movsr2, #250   ; (from following code,
; generating the constant 1000)
  0x83a0084a :  lslsr2, r2, #2 ; (from following code
; generating the constant 1000)
  0x83a0084c :  subsr3, r2, r3 ; (from following code, doing
; 1000 - x)
  0x83a0084e :  str r1, [sp, #80]  ; Store the y result

It ends up accessing memory at the location specified by the integer
curLine.mEndPoints.p0.x which is unlikely to be valid.

Compiler is g++ 4.4.0 as provided with the Android NDK r5b. Optimization is
turned on (O2). With optimization off, the issue does not occur.

Getting a small, self-contained, example is difficult since it is highly
sensitive to the surrounding code. Filing mainly to allow people using the NDK
to see why they might be having bad pointer accesses in situations where such
issues should be impossible.


[Bug rtl-optimization/49034] ARM optimizer generating incorrect code (causing bad pointer dereference)

2011-05-22 Thread michaelatnavman at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49034

--- Comment #2 from Michael Brown  2011-05-23 
06:38:35 UTC ---
Based on previous experiences, it'll be at least a couple of weeks to bring up
a similarly configured (cross-compiling darwin-x86 -> arm-eabi) FSF toolchain.

The command line is (paths and project-specific defines removed for clarity,
but otherwise unchanged):
arm-linux-androideabi-g++ -MMD -MP -MF foo.o.d.org -fpic -ffunction-sections
-funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__
-D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale
-msoft-float -fno-exceptions -fno-rtti -mthumb -Os -fomit-frame-pointer
-fno-strict-aliasing -finline-limit=64 -Wa,--noexecstack -fexceptions -frtti
-O2 -DNDEBUG -g -fexceptions -frtti -c foo.cpp -o foo.o

Yes, it's asking for no exceptions and no RTTI, and also for them to be
enabled. The wondrous inflexibilities of the android NDK ...

Preprocessed output is several MB, and I'm probably not allowed to post it
anyhow. Given how sensitive the bug is to surrounding code (changing only
peripherally related code causes the bug to vanish) it'll probably take another
couple of weeks (after getting the toolchain going) to get a decent test case
going.

As mentioned in the initial report, I don't really expect this to be fixed.
It's just to let people who are seeing bizarre or "impossible" SIGSEGV
exceptions a hint as to where to look. Given:
(a) the amount of work required to get a satisfactory bug report together is
large, and
(b) a workaround exists (turn off optimization), and
(b) no-one else seems to have run into this, and
(c) the bug is in a GCC version that was released two years ago, and
(d) the likelihood that due to the sensitivity of the bug to the surrounding
code, other unrelated changes in GCC will result in the test case failing to
tickle the bug in later versions even if the bug still being present,
it ends up on the pile of things that get worked on in the evenings when I have
time. Hence why it'll probably be a month if not longer before I can get a
useful test case together.