Author: Ben Shi Date: 2022-11-17T08:38:44+08:00 New Revision: 84ef7235732896530564289c8db59291a7d5413e
URL: https://github.com/llvm/llvm-project/commit/84ef7235732896530564289c8db59291a7d5413e DIFF: https://github.com/llvm/llvm-project/commit/84ef7235732896530564289c8db59291a7d5413e.diff LOG: [clang] Fix wrong ABI of AVRTiny. A scalar which exceeds 4 bytes should be returned via a stack slot, on an AVRTiny device. Reviewed By: aykevl Differential Revision: https://reviews.llvm.org/D138125 Added: clang/test/CodeGen/avr/return-value.c Modified: clang/lib/CodeGen/TargetInfo.cpp Removed: clang/test/CodeGen/avr/struct.c ################################################################################ diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index c57b0ddac75ad..fb6eb4aba60fc 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -8339,15 +8339,16 @@ class AVRABIInfo : public DefaultABIInfo { : 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 similarity index 92% rename from clang/test/CodeGen/avr/struct.c rename to clang/test/CodeGen/avr/return-value.c index dcd7d7a49f513..535bf8f3a4e9e 100644 --- a/clang/test/CodeGen/avr/struct.c +++ b/clang/test/CodeGen/avr/return-value.c @@ -33,12 +33,17 @@ struct s04 foo04(int a, int b) { 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 @@ struct s04 foo04(int a, int b) { // 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 {{.*}}) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits