[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