diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2014-11-17 11:18:10 +0000 |
---|---|---|
committer | Oliver Stannard <oliver.stannard@arm.com> | 2014-11-17 11:18:10 +0000 |
commit | 970b0d576c35c296111ffd9be6ffd04c294760db (patch) | |
tree | 242293bd7d14f3ddb30481a61bc325bde333a682 /llvm/test/CodeGen/ARM/thumb1-varalloc.ll | |
parent | 236b0ca79055779c4d024d66dcd0cbc44265df7f (diff) | |
download | bcm5719-llvm-970b0d576c35c296111ffd9be6ffd04c294760db.tar.gz bcm5719-llvm-970b0d576c35c296111ffd9be6ffd04c294760db.zip |
[Thumb1] Re-write emitThumbRegPlusImmediate
This was motivated by a bug which caused code like this to be
miscompiled:
declare void @take_ptr(i8*)
define void @test() {
%addr1.32 = alloca i8
%addr2.32 = alloca i32, i32 1028
call void @take_ptr(i8* %addr1)
ret void
}
This was emitting the following assembly to get the value of %addr1:
add r0, sp, #1020
add r0, r0, #8
However, "add r0, r0, #8" is not a valid Thumb1 instruction, and this
could not be assembled. The generated object file contained this,
resulting in r0 holding SP+8 rather tha SP+1028:
add r0, sp, #1020
add r0, sp, #8
This function looked like it could have caused miscompilations for
other combinations of registers and offsets (though I don't think it is
currently called with these), and the heuristic it used did not match
the emitted code in all cases.
llvm-svn: 222125
Diffstat (limited to 'llvm/test/CodeGen/ARM/thumb1-varalloc.ll')
-rw-r--r-- | llvm/test/CodeGen/ARM/thumb1-varalloc.ll | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/llvm/test/CodeGen/ARM/thumb1-varalloc.ll b/llvm/test/CodeGen/ARM/thumb1-varalloc.ll index 19c5dbeceab..8d5888d38f9 100644 --- a/llvm/test/CodeGen/ARM/thumb1-varalloc.ll +++ b/llvm/test/CodeGen/ARM/thumb1-varalloc.ll @@ -1,5 +1,7 @@ ; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s ; RUN: llc < %s -mtriple=thumbv6-apple-darwin -regalloc=basic | FileCheck %s +; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-apple-darwin +; RUN: llvm-objdump -triple=thumbv6-apple-darwin -d %t | FileCheck %s @__bar = external hidden global i8* @__baz = external hidden global i8* @@ -49,13 +51,13 @@ define void @test_local_var_addr() { %addr2 = alloca i8 ; CHECK: mov r0, sp -; CHECK: adds r0, r0, #{{[0-9]+}} -; CHECK: blx _take_ptr +; CHECK: adds r0, #{{[0-9]+}} +; CHECK: blx call void @take_ptr(i8* %addr1) ; CHECK: mov r0, sp -; CHECK: adds r0, r0, #{{[0-9]+}} -; CHECK: blx _take_ptr +; CHECK: adds r0, #{{[0-9]+}} +; CHECK: blx call void @take_ptr(i8* %addr2) ret void @@ -70,7 +72,7 @@ define void @test_simple_var() { ; CHECK: mov r0, sp ; CHECK-NOT: adds r0 -; CHECK: blx _take_ptr +; CHECK: blx call void @take_ptr(i8* %addr8) ret void } @@ -85,12 +87,12 @@ define void @test_local_var_addr_aligned() { %addr2 = bitcast i32* %addr2.32 to i8* ; CHECK: add r0, sp, #{{[0-9]+}} -; CHECK: blx _take_ptr +; CHECK: blx call void @take_ptr(i8* %addr1) ; CHECK: mov r0, sp ; CHECK-NOT: add r0 -; CHECK: blx _take_ptr +; CHECK: blx call void @take_ptr(i8* %addr2) ret void @@ -104,8 +106,35 @@ define void @test_local_var_big_offset() { %addr2.32 = alloca i32, i32 257 ; CHECK: add [[RTMP:r[0-9]+]], sp, #1020 -; CHECL: add r0, [[RTMP]], #8 -; CHECK: blx _take_ptr +; CHECK: adds [[RTMP]], #8 +; CHECK: blx + call void @take_ptr(i8* %addr1) + + ret void +} + +; Max range addressable with tADDrSPi +define void @test_local_var_offset_1020() { +; CHECK-LABEL: test_local_var_offset_1020 + %addr1 = alloca i8, i32 4 + %addr2 = alloca i8, i32 1020 + +; CHECK: add r0, sp, #1020 +; CHECK-NEXT: blx + call void @take_ptr(i8* %addr1) + + ret void +} + +; Max range addressable with tADDrSPi + tADDi8 +define void @test_local_var_offset_1275() { +; CHECK-LABEL: test_local_var_offset_1275 + %addr1 = alloca i8, i32 1 + %addr2 = alloca i8, i32 1275 + +; CHECK: add r0, sp, #1020 +; CHECK: adds r0, #255 +; CHECK-NEXT: blx call void @take_ptr(i8* %addr1) ret void |