2011-01-11 08:16:04 +08:00
|
|
|
; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s
|
2011-04-01 06:14:03 +08:00
|
|
|
; RUN: llc < %s -mtriple=thumbv6-apple-darwin -regalloc=basic | FileCheck %s
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-apple-darwin
|
2016-04-09 02:15:37 +08:00
|
|
|
; RUN: llvm-objdump -triple=thumbv6-apple-darwin -d %t | FileCheck %s
|
2011-01-11 08:16:04 +08:00
|
|
|
|
|
|
|
@__bar = external hidden global i8*
|
|
|
|
@__baz = external hidden global i8*
|
|
|
|
|
2014-10-21 05:28:41 +08:00
|
|
|
; rdar://8819685
|
2011-01-11 08:16:04 +08:00
|
|
|
define i8* @_foo() {
|
|
|
|
entry:
|
2014-10-21 05:28:41 +08:00
|
|
|
; CHECK-LABEL: foo:
|
2011-01-11 08:16:04 +08:00
|
|
|
|
|
|
|
%size = alloca i32, align 4
|
2015-02-28 05:17:42 +08:00
|
|
|
%0 = load i8*, i8** @__bar, align 4
|
2011-01-11 08:16:04 +08:00
|
|
|
%1 = icmp eq i8* %0, null
|
|
|
|
br i1 %1, label %bb1, label %bb3
|
2011-04-01 06:14:03 +08:00
|
|
|
; CHECK: bne
|
2011-01-11 08:16:04 +08:00
|
|
|
|
|
|
|
bb1:
|
|
|
|
store i32 1026, i32* %size, align 4
|
|
|
|
%2 = alloca [1026 x i8], align 1
|
2011-04-01 06:14:03 +08:00
|
|
|
; CHECK: mov [[R0:r[0-9]+]], sp
|
|
|
|
; CHECK: adds {{r[0-9]+}}, [[R0]], {{r[0-9]+}}
|
[opaque pointer type] Add textual IR support for explicit type parameter to getelementptr instruction
One of several parallel first steps to remove the target type of pointers,
replacing them with a single opaque pointer type.
This adds an explicit type parameter to the gep instruction so that when the
first parameter becomes an opaque pointer type, the type to gep through is
still available to the instructions.
* This doesn't modify gep operators, only instructions (operators will be
handled separately)
* Textual IR changes only. Bitcode (including upgrade) and changing the
in-memory representation will be in separate changes.
* geps of vectors are transformed as:
getelementptr <4 x float*> %x, ...
->getelementptr float, <4 x float*> %x, ...
Then, once the opaque pointer type is introduced, this will ultimately look
like:
getelementptr float, <4 x ptr> %x
with the unambiguous interpretation that it is a vector of pointers to float.
* address spaces remain on the pointer, not the type:
getelementptr float addrspace(1)* %x
->getelementptr float, float addrspace(1)* %x
Then, eventually:
getelementptr float, ptr addrspace(1) %x
Importantly, the massive amount of test case churn has been automated by
same crappy python code. I had to manually update a few test cases that
wouldn't fit the script's model (r228970,r229196,r229197,r229198). The
python script just massages stdin and writes the result to stdout, I
then wrapped that in a shell script to handle replacing files, then
using the usual find+xargs to migrate all the files.
update.py:
import fileinput
import sys
import re
ibrep = re.compile(r"(^.*?[^%\w]getelementptr inbounds )(((?:<\d* x )?)(.*?)(| addrspace\(\d\)) *\*(|>)(?:$| *(?:%|@|null|undef|blockaddress|getelementptr|addrspacecast|bitcast|inttoptr|\[\[[a-zA-Z]|\{\{).*$))")
normrep = re.compile( r"(^.*?[^%\w]getelementptr )(((?:<\d* x )?)(.*?)(| addrspace\(\d\)) *\*(|>)(?:$| *(?:%|@|null|undef|blockaddress|getelementptr|addrspacecast|bitcast|inttoptr|\[\[[a-zA-Z]|\{\{).*$))")
def conv(match, line):
if not match:
return line
line = match.groups()[0]
if len(match.groups()[5]) == 0:
line += match.groups()[2]
line += match.groups()[3]
line += ", "
line += match.groups()[1]
line += "\n"
return line
for line in sys.stdin:
if line.find("getelementptr ") == line.find("getelementptr inbounds"):
if line.find("getelementptr inbounds") != line.find("getelementptr inbounds ("):
line = conv(re.match(ibrep, line), line)
elif line.find("getelementptr ") != line.find("getelementptr ("):
line = conv(re.match(normrep, line), line)
sys.stdout.write(line)
apply.sh:
for name in "$@"
do
python3 `dirname "$0"`/update.py < "$name" > "$name.tmp" && mv "$name.tmp" "$name"
rm -f "$name.tmp"
done
The actual commands:
From llvm/src:
find test/ -name *.ll | xargs ./apply.sh
From llvm/src/tools/clang:
find test/ -name *.mm -o -name *.m -o -name *.cpp -o -name *.c | xargs -I '{}' ../../apply.sh "{}"
From llvm/src/tools/polly:
find test/ -name *.ll | xargs ./apply.sh
After that, check-all (with llvm, clang, clang-tools-extra, lld,
compiler-rt, and polly all checked out).
The extra 'rm' in the apply.sh script is due to a few files in clang's test
suite using interesting unicode stuff that my python script was throwing
exceptions on. None of those files needed to be migrated, so it seemed
sufficient to ignore those cases.
Reviewers: rafael, dexonsmith, grosser
Differential Revision: http://reviews.llvm.org/D7636
llvm-svn: 230786
2015-02-28 03:29:02 +08:00
|
|
|
%3 = getelementptr inbounds [1026 x i8], [1026 x i8]* %2, i32 0, i32 0
|
2011-01-11 08:16:04 +08:00
|
|
|
%4 = call i32 @_called_func(i8* %3, i32* %size) nounwind
|
|
|
|
%5 = icmp eq i32 %4, 0
|
|
|
|
br i1 %5, label %bb2, label %bb3
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%6 = call i8* @strdup(i8* %3) nounwind
|
|
|
|
store i8* %6, i8** @__baz, align 4
|
|
|
|
br label %bb3
|
|
|
|
|
|
|
|
bb3:
|
|
|
|
%.0 = phi i8* [ %0, %entry ], [ %6, %bb2 ], [ %3, %bb1 ]
|
|
|
|
; CHECK: subs r4, #5
|
|
|
|
; CHECK-NEXT: mov sp, r4
|
|
|
|
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
|
|
|
|
ret i8* %.0
|
|
|
|
}
|
|
|
|
|
|
|
|
declare noalias i8* @strdup(i8* nocapture) nounwind
|
2013-07-14 04:38:47 +08:00
|
|
|
declare i32 @_called_func(i8*, i32*) nounwind
|
2014-10-21 05:28:41 +08:00
|
|
|
|
|
|
|
; Simple variable ending up *at* sp.
|
|
|
|
define void @test_simple_var() {
|
|
|
|
; CHECK-LABEL: test_simple_var:
|
|
|
|
|
|
|
|
%addr32 = alloca i32
|
|
|
|
%addr8 = bitcast i32* %addr32 to i8*
|
|
|
|
|
|
|
|
; CHECK: mov r0, sp
|
|
|
|
; CHECK-NOT: adds r0
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK: bl
|
2014-10-21 05:28:41 +08:00
|
|
|
call void @take_ptr(i8* %addr8)
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; Simple variable ending up at aligned offset from sp.
|
|
|
|
define void @test_local_var_addr_aligned() {
|
|
|
|
; CHECK-LABEL: test_local_var_addr_aligned:
|
|
|
|
|
|
|
|
%addr1.32 = alloca i32
|
|
|
|
%addr1 = bitcast i32* %addr1.32 to i8*
|
|
|
|
%addr2.32 = alloca i32
|
|
|
|
%addr2 = bitcast i32* %addr2.32 to i8*
|
|
|
|
|
|
|
|
; CHECK: add r0, sp, #{{[0-9]+}}
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK: bl
|
2014-10-21 05:28:41 +08:00
|
|
|
call void @take_ptr(i8* %addr1)
|
|
|
|
|
|
|
|
; CHECK: mov r0, sp
|
|
|
|
; CHECK-NOT: add r0
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK: bl
|
2014-10-21 05:28:41 +08:00
|
|
|
call void @take_ptr(i8* %addr2)
|
|
|
|
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; Simple variable ending up at aligned offset from sp.
|
|
|
|
define void @test_local_var_big_offset() {
|
|
|
|
; CHECK-LABEL: test_local_var_big_offset:
|
|
|
|
%addr1.32 = alloca i32, i32 257
|
|
|
|
%addr1 = bitcast i32* %addr1.32 to i8*
|
|
|
|
%addr2.32 = alloca i32, i32 257
|
|
|
|
|
|
|
|
; CHECK: add [[RTMP:r[0-9]+]], sp, #1020
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
; CHECK: adds [[RTMP]], #8
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK: bl
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
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
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK-NEXT: bl
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
call void @take_ptr(i8* %addr1)
|
|
|
|
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
2015-02-25 22:41:06 +08:00
|
|
|
; Max range addressable with tADDrSPi + tADDi8 is 1275, however the automatic
|
|
|
|
; 4-byte aligning of objects on the stack combined with 8-byte stack alignment
|
|
|
|
; means that 1268 is the max offset we can use.
|
|
|
|
define void @test_local_var_offset_1268() {
|
|
|
|
; CHECK-LABEL: test_local_var_offset_1268
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
%addr1 = alloca i8, i32 1
|
2015-02-25 22:41:06 +08:00
|
|
|
%addr2 = alloca i8, i32 1268
|
[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
2014-11-17 19:18:10 +08:00
|
|
|
|
|
|
|
; CHECK: add r0, sp, #1020
|
2015-02-25 22:41:06 +08:00
|
|
|
; CHECK: adds r0, #248
|
2016-05-11 03:17:47 +08:00
|
|
|
; CHECK-NEXT: bl
|
2014-10-21 05:28:41 +08:00
|
|
|
call void @take_ptr(i8* %addr1)
|
|
|
|
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @take_ptr(i8*)
|