[cfe-dev] Code generated for pointer pair -> pointer + size -> pointer pair conversion

Benjamin Kramer benny.kra at gmail.com
Sun Jun 16 09:13:41 PDT 2013


On 16.06.2013, at 13:59, Stephan Tolksdorf <st at quanttec.com> wrote:

> Hi,
> 
> clang emits the following x64 code for `vector.data() + vector.size()`
> (where vector is a std::vector<int32> instance that contains two internal pointers that point to the beginning and the end of an array):
> 
>  movq	(%rdi), %rcx  // rdi is a pointer to the vector
>  movq	8(%rdi), %rax
>  subq	%rcx, %rax
>  andq	$-4, %rax
>  addq	%rcx, %rax
> 
> Is there any way to tell clang in the vector implementation that the array is aligned, so that it could reduce this code to a simple load
> `movq 8(%rdi), %rax`?
> 
> This kind of optimization would be helpful for inlined code that converts back and forth between a pointer pair representation and pointer + size representation of an array reference.

The optimizer already knows this. Here's the IR for a pattern like yours:

  %sub.ptr.lhs.cast = ptrtoint i32* %1 to i64
  %sub.ptr.rhs.cast = ptrtoint i32* %0 to i64
  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
  %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2
  %add.ptr = getelementptr inbounds i32* %0, i64 %sub.ptr.div

The "exact" bit on the ashr is a hint that the shift only shifts out zeros (because the pointers are aligned). The getelementptr gets lowered into adds later in the SelectionDAG, but the "exact" bit is lost by then. It has to assume that the value may be unaligned and inserts the andq $-4.

I see two ways to fix this:

1. Teach SelectionDAG about "exact" bits. I don't think this is possible with our current infrastructure.
2. Teach InstCombine how to fuse ashrs and getelementptr instructions. Not sure how tricky this is.

- Ben



More information about the cfe-dev mailing list