Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -8435,6 +8435,10 @@ LargeRet = true; return getNaturalAlignIndirect(Ty); } + // An i8 return value should not be extended to i16, since AVR has 8-bit + // registers. + if (Ty->isIntegralOrEnumerationType() && getContext().getTypeSize(Ty) <= 8) + return ABIArgInfo::getDirect(); // Otherwise we follow the default way which is compatible. return DefaultABIInfo::classifyReturnType(Ty); } Index: clang/test/CodeGen/avr/avr-builtins.c =================================================================== --- clang/test/CodeGen/avr/avr-builtins.c +++ clang/test/CodeGen/avr/avr-builtins.c @@ -8,7 +8,7 @@ return __builtin_bitreverse8(data); } -// CHECK: define{{.*}} zeroext i8 @bitrev8 +// CHECK: define{{.*}} i8 @bitrev8 // CHECK: i8 @llvm.bitreverse.i8(i8 unsigned int bitrev16(unsigned int data) { @@ -35,7 +35,7 @@ return __builtin_rotateleft8(x, y); } -// CHECK: define{{.*}} zeroext i8 @rotleft8 +// CHECK: define{{.*}} i8 @rotleft8 // CHECK: i8 @llvm.fshl.i8(i8 unsigned int rotleft16(unsigned int x, unsigned int y) { @@ -62,7 +62,7 @@ return __builtin_rotateright8(x, y); } -// CHECK: define{{.*}} zeroext i8 @rotright8 +// CHECK: define{{.*}} i8 @rotright8 // CHECK: i8 @llvm.fshr.i8(i8 unsigned int rotright16(unsigned int x, unsigned int y) {