[llvm-bugs] [Bug 32799] New: ARMv5 load codegen ignores alignment
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Apr 26 02:32:01 PDT 2017
https://bugs.llvm.org/show_bug.cgi?id=32799
Bug ID: 32799
Summary: ARMv5 load codegen ignores alignment
Product: libraries
Version: trunk
Hardware: Other
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Backend: ARM
Assignee: unassignedbugs at nondot.org
Reporter: llvm at joakim.fea.st
CC: llvm-bugs at lists.llvm.org
ldc, the llvm D compiler, uses the following function to read possibly
unaligned integers in its exception-handling code:
uint udata4_read(ref ubyte* addr)
{
// read udata4 from possibly unaligned `addr`
import core.stdc.string : memcpy;
uint udata4;
memcpy(&udata4, addr, udata4.sizeof);
addr += udata4.sizeof;
return udata4;
}
https://github.com/ldc-developers/druntime/blob/24ce3878d8debf6cca9bb4f0a55bad6480f8c5de/src/ldc/eh/common.d#L80
Unoptimized, it works fine and is turned into the following IR and ARM assembly
with these llvm options, "-mtriple=armv5tej-none-linux-gnueabi -float-abi=soft
-gcc=arm-linux-gnueabi-gcc":
IR
; Function Attrs: noinline nounwind optnone
define i32 @_D3ldc2eh6common11udata4_readFKPhZk(i8** dereferenceable(4) %addr)
local_unnamed_addr #2 comdat {
%udata4 = alloca i32, align 4 ; [#uses = 4, size/byte = 4]
store i32 0, i32* %udata4
%1 = bitcast i32* %udata4 to i8* ; [#uses = 1]
%2 = load i8*, i8** %addr ; [#uses = 1]
%3 = call i8* @memcpy(i8* %1, i8* %2, i32 4) #0 ; [#uses = 0]
%4 = load i8*, i8** %addr ; [#uses = 1]
%5 = getelementptr i8, i8* %4, i32 4 ; [#uses = 1, type = i8*]
store i8* %5, i8** %addr
%6 = load i32, i32* %udata4 ; [#uses = 0]
%7 = load i32, i32* %udata4 ; [#uses = 1]
ret i32 %7
}
ASM
.section
.text._D3ldc2eh6common11udata4_readFKPhZk,"axG",%progbits,_D3ldc2eh6common11udata4_readFKPhZk,comdat
.globl _D3ldc2eh6common11udata4_readFKPhZk
.p2align 2
.type _D3ldc2eh6common11udata4_readFKPhZk,%function
_D3ldc2eh6common11udata4_readFKPhZk:
.fnstart
.save {r4, lr}
push {r4, lr}
.pad #8
sub sp, sp, #8
mov r4, r0
mov r0, #0
str r0, [sp, #4]
ldr r1, [r4]
add r0, sp, #4
mov r2, #4
bl memcpy
ldr r0, [r4]
add r0, r0, #4
str r0, [r4]
ldr r0, [sp, #4]
add sp, sp, #8
pop {r4, lr}
bx lr
.Lfunc_end1:
.size _D3ldc2eh6common11udata4_readFKPhZk,
.Lfunc_end1-_D3ldc2eh6common11udata4_readFKPhZk
.cantunwind
.fnend
Once aggressively optimized, it turns into this LL and IR, which causes bad
data to be read in and eventually errors out:
IR
; Function Attrs: norecurse nounwind
define i32 @_D3ldc2eh6common11udata4_readFKPhZk(i8** nocapture
dereferenceable(4) %addr) local_unnamed_addr #2 comdat {
%1 = load i8*, i8** %addr, align 4 ; [#uses = 2]
%2 = bitcast i8* %1 to i32* ; [#uses = 1]
%3 = load i32, i32* %2, align 1 ; [#uses = 1]
%4 = getelementptr i8, i8* %1, i32 4 ; [#uses = 1, type = i8*]
store i8* %4, i8** %addr, align 4
ret i32 %3
}
ASM
.section
.text._D3ldc2eh6common11udata4_readFKPhZk,"axG",%progbits,_D3ldc2eh6common11udata4_readFKPhZk,comdat
.globl _D3ldc2eh6common11udata4_readFKPhZk
.p2align 2
.type _D3ldc2eh6common11udata4_readFKPhZk,%function
_D3ldc2eh6common11udata4_readFKPhZk:
.fnstart
ldr r2, [r0]
ldr r1, [r2], #4
str r2, [r0]
mov r0, r1
bx lr
.Lfunc_end1:
.size _D3ldc2eh6common11udata4_readFKPhZk,
.Lfunc_end1-_D3ldc2eh6common11udata4_readFKPhZk
.cantunwind
.fnend
The problem appears to be that the load with align 1 from the latter IR is
turned into a ldr + 4 in the ASM, an instruction which doesn't allow unaligned
accesses on ARMv5:
The ARMv6 architecture introduced the first hardware support for unaligned
accesses. ARM11 and Cortex-A/R processors can deal with unaligned accesses in
hardware, removing the need for software routines.
Support for unaligned accesses is limited to a sub-set of load/store
instructions:
LDRB/LDRSB/STRB
LDRH/LDRSH/STRH
LDR/STR
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html
This bug was found by an ldc developer, more discussion in this github thread:
https://github.com/ldc-developers/ldc/issues/2058#issuecomment-296656483
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170426/f7dc85df/attachment-0001.html>
More information about the llvm-bugs
mailing list