diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -8339,15 +8339,16 @@ : DefaultABIInfo(CGT), ParamRegs(NPR), RetRegs(NRR) {} ABIArgInfo classifyReturnType(QualType Ty, bool &LargeRet) const { - if (isAggregateTypeForABI(Ty)) { - // On AVR, a return struct with size less than or equals to 8 bytes is - // returned directly via registers R18-R25. On AVRTiny, a return struct - // with size less than or equals to 4 bytes is returned directly via - // registers R22-R25. - if (getContext().getTypeSize(Ty) <= RetRegs * 8) - return ABIArgInfo::getDirect(); - // A return struct with larger size is returned via a stack - // slot, along with a pointer to it as the function's implicit argument. + // On AVR, a return struct with size less than or equals to 8 bytes is + // returned directly via registers R18-R25. On AVRTiny, a return struct + // with size less than or equals to 4 bytes is returned directly via + // registers R22-R25. + if (isAggregateTypeForABI(Ty) && + getContext().getTypeSize(Ty) <= RetRegs * 8) + return ABIArgInfo::getDirect(); + // A return value (struct or scalar) with larger size is returned via a + // stack slot, along with a pointer as the function's implicit argument. + if (getContext().getTypeSize(Ty) > RetRegs * 8) { LargeRet = true; return getNaturalAlignIndirect(Ty); } diff --git a/clang/test/CodeGen/avr/struct.c b/clang/test/CodeGen/avr/return-value.c rename from clang/test/CodeGen/avr/struct.c rename to clang/test/CodeGen/avr/return-value.c --- a/clang/test/CodeGen/avr/struct.c +++ b/clang/test/CodeGen/avr/return-value.c @@ -33,12 +33,17 @@ return a0; } +long long fooi64(void) { + return 0xaa5533; +} + // AVR: %struct.s10 = type { i16, i16, i16, i16, i16 } // AVR: %struct.s06 = type { i16, i16, i16 } // AVR: %struct.s04 = type { i16, i16 } // AVR: define{{.*}} void @foo10(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c) // AVR: define{{.*}} %struct.s06 @foo06(i16 noundef %a, i16 noundef %b, i16 noundef %c) // AVR: define{{.*}} %struct.s04 @foo04(i16 noundef %a, i16 noundef %b) +// AVR: define{{.*}} i64 @fooi64() // TINY: %struct.s10 = type { i16, i16, i16, i16, i16 } // TINY: %struct.s06 = type { i16, i16, i16 } @@ -46,3 +51,4 @@ // TINY: define{{.*}} void @foo10(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c) // TINY: define{{.*}} void @foo06(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c) // TINY: define{{.*}} %struct.s04 @foo04(i16 noundef %a, i16 noundef %b) +// TINY: define{{.*}} void @fooi64(ptr {{.*}})