[cfe-dev] Pointer Arithmetic
Keith Bauer
onesadcookie at gmail.com
Thu Jul 12 16:53:20 PDT 2007
Should also say, whilst I'm here, it compiles:
int *test1(int *a) { return a + 1; }
int *test2(int *a) { return 1 + a; }
int *test3(int *a) { return a - 1; }
int test4(int *a, int *b) { return a - b; }
into:
; ModuleID = 'foo'
define i32* @test1(i32* %a) {
entry:
%a.addr = alloca i32* ; <i32**> [#uses=2]
%allocapt = bitcast i32 undef to i32 ; <i32> [#uses=0]
store i32* %a, i32** %a.addr
%tmp = load i32** %a.addr ; <i32*> [#uses=1]
%add.ptr = getelementptr i32* %tmp, i32 1 ; <i32*> [#uses=1]
ret i32* %add.ptr
; No predecessors!
ret i32* undef
}
define i32* @test2(i32* %a) {
entry:
%a.addr = alloca i32* ; <i32**> [#uses=2]
%allocapt = bitcast i32 undef to i32 ; <i32> [#uses=0]
store i32* %a, i32** %a.addr
%tmp = load i32** %a.addr ; <i32*> [#uses=1]
%add.ptr = getelementptr i32* %tmp, i32 1 ; <i32*> [#uses=1]
ret i32* %add.ptr
; No predecessors!
ret i32* undef
}
define i32* @test3(i32* %a) {
entry:
%a.addr = alloca i32* ; <i32**> [#uses=2]
%allocapt = bitcast i32 undef to i32 ; <i32> [#uses=0]
store i32* %a, i32** %a.addr
%tmp = load i32** %a.addr ; <i32*> [#uses=1]
%sub.ptr.neg = sub i32 0, 1 ; <i32> [#uses=1]
%sub.ptr = getelementptr i32* %tmp, i32 %sub.ptr.neg ; <i32*> [#uses=1]
ret i32* %sub.ptr
; No predecessors!
ret i32* undef
}
define i32 @test4(i32* %a, i32* %b) {
entry:
%a.addr = alloca i32* ; <i32**> [#uses=2]
%b.addr = alloca i32* ; <i32**> [#uses=2]
%allocapt = bitcast i32 undef to i32 ; <i32> [#uses=0]
store i32* %a, i32** %a.addr
store i32* %b, i32** %b.addr
%tmp = load i32** %a.addr ; <i32*> [#uses=1]
%tmp1 = load i32** %b.addr ; <i32*> [#uses=1]
%sub.ptr.lhs.cast = ptrtoint i32* %tmp to i32 ; <i32> [#uses=1]
%sub.ptr.rhs.cast = ptrtoint i32* %tmp1 to i32 ; <i32> [#uses=1]
%sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast ; <i32> [#uses=1]
%sub.ptr.div = sdiv i32 %sub.ptr.sub, 4 ; <i32> [#uses=1]
ret i32 %sub.ptr.div
; No predecessors!
ret i32 undef
}
which gets optimized to:
; ModuleID = '<stdin>'
define i32* @test1(i32* %a) {
entry:
%add.ptr = getelementptr i32* %a, i32 1 ; <i32*> [#uses=1]
ret i32* %add.ptr
}
define i32* @test2(i32* %a) {
entry:
%add.ptr = getelementptr i32* %a, i32 1 ; <i32*> [#uses=1]
ret i32* %add.ptr
}
define i32* @test3(i32* %a) {
entry:
%sub.ptr = getelementptr i32* %a, i32 -1 ; <i32*> [#uses=1]
ret i32* %sub.ptr
}
define i32 @test4(i32* %a, i32* %b) {
entry:
%sub.ptr.lhs.cast = ptrtoint i32* %a to i32 ; <i32> [#uses=1]
%sub.ptr.rhs.cast = ptrtoint i32* %b to i32 ; <i32> [#uses=1]
%sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast ; <i32> [#uses=1]
%sub.ptr.div = sdiv i32 %sub.ptr.sub, 4 ; <i32> [#uses=1]
ret i32 %sub.ptr.div
}
(I guess the div can't be optimized to a shift because it's signed division?)
-Keith
More information about the cfe-dev
mailing list