Hello.

I come back to this older thread.

I'd also like to thank Peter Lawrence for the insightful answer (see below his email, if interested). Actually I would like to add that the C11 standard, Section 6.3.1.1, talks about integer promotions, which explains why the C language requires short arithmetic to be promoted to the size of int. See also https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules .

I would like to give an answer to Craig Topper: indeed I have a simple very interesting case where these promotions happen - the Floyd-Warshall algorithm, with the below program (also try the example at https://www.geeksforgeeks.org/integer-promotions-in-c/) . But in all cases do give clang -O0 to emit unoptimized LLVM IR.

#define SIZE 128

short path[SIZE][SIZE];

void FloydWarshall() {

int i, j, k;

for (k = 0; k < SIZE; k++) {

for (i = 0; i < SIZE; ++i) {

short pik = path[i][k];

for (j = 0; j < SIZE; j++) {

path[i][j] = path[i][j] < pik + path[k][j] ?

path[i][j] : pik + path[k][j];

}

}

}

}

The innermost's loop body is translated to the following UNoptimized LLVM IR code - see lines with comment "IMPORTANT":

for.body8: ; preds = %for.cond6

%6 = load i32, i32* %j, align 4

%idxprom9 = sext i32 %6 to i64

%7 = load i32, i32* %i, align 4

%idxprom10 = sext i32 %7 to i64

%arrayidx11 = getelementptr inbounds [256 x [256 x i16]], [256 x [256 x i16]]* @path, i64 0, i64 %idxprom10

%arrayidx12 = getelementptr inbounds [256 x i16], [256 x i16]* %arrayidx11, i64 0, i64 %idxprom9

%8 = load i16, i16* %arrayidx12

%conv = sext i16 %8 to i32 ; IMPORTANT

%9 = load i16, i16* %pik

%conv13 = sext i16 %9 to i32 ; IMPORTANT

%10 = load i32, i32* %j, align 4

%idxprom14 = sext i32 %10 to i64

%11 = load i32, i32* %k, align 4

%idxprom15 = sext i32 %11 to i64

%arrayidx16 = getelementptr inbounds [256 x [256 x i16]], [256 x [256 x i16]]* @path, i64 0, i64 %idxprom15

%arrayidx17 = getelementptr inbounds [256 x i16], [256 x i16]* %arrayidx16, i64 0, i64 %idxprom14

%12 = load i16, i16* %arrayidx17, align 2, !dbg !61

%conv18 = sext i16 %12 to i32

%add = add nsw i32 %conv13, %conv18

%add = add nsw i16 %9, %12 ; IMPORTANT

%cmp19 = icmp slt i32 %conv, %add

%cmp19 = icmp slt i16 %8, %add ; IMPORTANT

br i1 %cmp19, label %cond.true, label %cond.false

Best regards,

Alex