Alexandre Colucci
2012-Jan-24 08:45 UTC
[LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
In practice all Apple hardwares support misaligned accesses for single-register loads and stores. If a pointer is not aligned, LLVM should not use the double-register loads and stores. It should keep the two single-register loads instead of trying to optimize them as one unsupported double-register load. Note that this code compiled with GCC 4.2 runs perfectly whereas LLVM will produce a binary that crashes: LLVM breaks existing source code. Alexandre> The problem is in your code, not the compiler. You're casting an unaligned char* to an int*, even though an int* pointer must be 4-byte aligned in every ARM ABI that I've ever seen. > > On Jan 23, 2012, at 6:14 AM, Alexandre Colucci wrote: > >> Hi, >> >> I think I discovered a major armv7 optimization bug in Clang. I create a simple test case which exhibits the issue. >> When you compile the attached file for armv7 with optimizations turned on (O2, O3 or Os), the binary generated led to a crash. >> The issue can't be reproduced when using GCC 4.2. It can't be reproduced with Clang when the optimization is turned off (O0). >> This issue can be reproduced with Xcode 4.2.1 and Xcode 4.3 Developer Preview 3 (4E71d). >> >> The LLVM optimizer coalesces two loads into an ARM 'ldrd' double-load instruction. Unfortunately, some ARM hardware platforms (including all of Apple's) support misaligned accesses for single-register loads and stores ('ldr' and 'str' instructions), but not for double-register loads and stores ('ldrd' and 'strd' instructions.). >> On those platforms, the attached code triggers an address error when passed a misaligned address if it's compiled by LLVM with the optimizer enabled, but not if it's compiled by gcc, or by LLVM with the optimizer disabled. >> At a minimum, there should be an option to disable the generation of 'ldrd' and 'strd', or the automatic coalescing of two loads that just happen to be nearby. >> >> I haven't found any bugs similar in the LLVM bug database. It is a known issue? This looks like a major optimization issue. >> >> Thanks, >> Alexandre >> >> <main.m>_______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >
James Molloy
2012-Jan-24 09:07 UTC
[LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
Hi Alexandre, The platform ABIs usually state that a pointer must be aligned to the same alignment as its pointee type requires. If you need it I can look it up and quote it for you, but I'm pretty sure this is the case. Cheers, James -----Original Message----- From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Alexandre Colucci Sent: 24 January 2012 08:46 To: Bob Wilson Cc: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?) In practice all Apple hardwares support misaligned accesses for single-register loads and stores. If a pointer is not aligned, LLVM should not use the double-register loads and stores. It should keep the two single-register loads instead of trying to optimize them as one unsupported double-register load. Note that this code compiled with GCC 4.2 runs perfectly whereas LLVM will produce a binary that crashes: LLVM breaks existing source code. Alexandre> The problem is in your code, not the compiler. You're casting anunaligned char* to an int*, even though an int* pointer must be 4-byte aligned in every ARM ABI that I've ever seen.> > On Jan 23, 2012, at 6:14 AM, Alexandre Colucci wrote: > >> Hi, >> >> I think I discovered a major armv7 optimization bug in Clang. I create asimple test case which exhibits the issue.>> When you compile the attached file for armv7 with optimizations turned on(O2, O3 or Os), the binary generated led to a crash.>> The issue can't be reproduced when using GCC 4.2. It can't be reproducedwith Clang when the optimization is turned off (O0).>> This issue can be reproduced with Xcode 4.2.1 and Xcode 4.3 DeveloperPreview 3 (4E71d).>> >> The LLVM optimizer coalesces two loads into an ARM 'ldrd' double-loadinstruction. Unfortunately, some ARM hardware platforms (including all of Apple's) support misaligned accesses for single-register loads and stores ('ldr' and 'str' instructions), but not for double-register loads and stores ('ldrd' and 'strd' instructions.).>> On those platforms, the attached code triggers an address error whenpassed a misaligned address if it's compiled by LLVM with the optimizer enabled, but not if it's compiled by gcc, or by LLVM with the optimizer disabled.>> At a minimum, there should be an option to disable the generation of'ldrd' and 'strd', or the automatic coalescing of two loads that just happen to be nearby.>> >> I haven't found any bugs similar in the LLVM bug database. It is a knownissue? This looks like a major optimization issue.>> >> Thanks, >> Alexandre >> >> <main.m>_______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >_______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
David Blaikie
2012-Jan-24 16:09 UTC
[LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
> Note that this code compiled with GCC 4.2 runs perfectly whereas LLVM will produce a binary that crashes: LLVM breaks existing source code.On this point: This is not uncommon - and the very nature of "Undefined Behaviour". This reason alone is not enough to justify a change to Clang. We/you would need to show that the behaviour is defined & Clang is violating that definition. Chris has posted about the general principle at length starting here: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
Esperanza de Escobar
2012-Jan-24 16:36 UTC
[LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
No one is arguing that there aren't ABI specs or LLVM design guidelines that say that unaligned accesses "should not", "could not" or "aren't guaranteed to" work, because it's besides the point. The point is that unaligned 32-bit loads and stores *work in practice* on every single ARM device Apple has ever manufactured. I'm not a hardware person, but I'm guessing it takes a non-negligible amount of silicon to support them. With Xcode's switch to LLVM, this deployed silicon has suddenly become off-limits because of a single overzealous optimization. The only possible workarounds are assembly code and turning the optimizer off altogether. It would be one thing if the optimizer generated ldrd/strd for 64-bit loads and stores only. But it actually goes as far as taking two separate 32-bit accesses and merging them into one silently-incompatible 64-bit access. These two accesses could be unrelated to one another in the context of the code at hand, and even syntactically distant. This introduces a stealth crash into Apple-only code that was bug-free under gcc. And realizing what's going on requires familiarity with ARM assembly. With a bit of googling you'll find other support board posts asking "Why is my code suddenly crashing after upgrading Xcode?" Unfortunately, there is no way to turn this optimization off. Not to mention that it's not much of an optimization at all. I'd be surprised if you could measure a performance improvement on a real-world program with less than a million iterations, maybe orders more. You can measure its damage pretty significantly, though. We've already spent a lot of hours tracking down unaligned accesses and wrapping them in assembly macros. Which of course ends up disabling other, actually useful optimizations. And with a large codebase, we can't be sure we've found every last one yet. Whether this optimization is academically acceptable or not, its net impact in real-world terms is exceedingly negative. EdE On 1/24/12, David Blaikie <dblaikie at gmail.com> wrote:>> Note that this code compiled with GCC 4.2 runs perfectly whereas LLVM will >> produce a binary that crashes: LLVM breaks existing source code. > > On this point: > This is not uncommon - and the very nature of "Undefined Behaviour". > This reason alone is not enough to justify a change to Clang. We/you > would need to show that the behaviour is defined & Clang is violating > that definition. > > Chris has posted about the general principle at length starting here: > http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Possibly Parallel Threads
- [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
- [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
- [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
- [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)
- [LLVMdev] Use of 'ldrd' instructions with unaligned addresses on armv7 (Major bug in LLVM optimizer?)