Why int variable get promoted to i64

Hi, all

  I found in some cases the int variable get promoted to i64,
although I think it should i32. I use the online demo
(http://llvm.org/demo). And below is the test case.

------------- test case -------------
int test(int x, int y, int n) {
  int i = 0;
  int sum = 0;
  for ( ; i < n; i++) {
    sum += x[i] * y[i];
  }
  return sum;
}

Because you are compiling for a 64-bit system which uses LP64. As such pointers are 64-bit in length… while integers remain defined as 32-bits.

So why 64-bits for i? The compiler is treating index variables special. Index variables need to be able to index 64-bits of space and in fact you’ll see the promotion here:

for.body:                                         ; preds = %for.cond
  %tmp2 = load i32* %i                            ; <i32> [#uses=1]
  %tmp3 = load i32** %x.addr                      ; <i32*> [#uses=1]
  %idxprom = sext i32 %tmp2 to i64                ; <i64> [#uses=1]
  %arrayidx = getelementptr inbounds i32* %tmp3, i64 %idxprom ; <i32*> [#uses=1]

Cheers,

Joe

The code in clang that performs this promotion for array subscript expressions is in CGExpr.cpp:

LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {

…snip…

// Extend or truncate the index type to 32 or 64-bits.
if (Idx->getType() != IntPtrTy)
Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, “idxprom”);

Cheers,

Joe

Because you are compiling for a 64-bit system which uses LP64. As such pointers are 64-bit in length... while integers remain defined as 32-bits.

So why 64-bits for i? The compiler is treating index variables special. Index variables need to be able to index 64-bits of space and in fact you'll see the promotion here:

for.body: ; preds = %for.cond
  %tmp2 = load i32* %i ; <i32> [#uses=1]
  %tmp3 = load i32** %x.addr ; <i32*> [#uses=1]
  %idxprom = sext i32 %tmp2 to i64 ; <i64> [#uses=1]
  %arrayidx = getelementptr inbounds i32* %tmp3, i64 %idxprom ; <i32*> [#uses=1]

  Indeed, the index variable "int i" won't be promoted if it
is not used in the loop body.

------------- test case --------------
int test(int x, int y, int n) {
  int i = 0;
  int sum = 0;
  for( ; i < n; i++) {
    sum += x[2] + y[2];
  }
  return sum;
}