Skip to content

Commit 84ef723

Browse files
committed
[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
1 parent 3c448c2 commit 84ef723

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8339,15 +8339,16 @@ class AVRABIInfo : public DefaultABIInfo {
83398339
: DefaultABIInfo(CGT), ParamRegs(NPR), RetRegs(NRR) {}
83408340

83418341
ABIArgInfo classifyReturnType(QualType Ty, bool &LargeRet) const {
8342-
if (isAggregateTypeForABI(Ty)) {
8343-
// On AVR, a return struct with size less than or equals to 8 bytes is
8344-
// returned directly via registers R18-R25. On AVRTiny, a return struct
8345-
// with size less than or equals to 4 bytes is returned directly via
8346-
// registers R22-R25.
8347-
if (getContext().getTypeSize(Ty) <= RetRegs * 8)
8348-
return ABIArgInfo::getDirect();
8349-
// A return struct with larger size is returned via a stack
8350-
// slot, along with a pointer to it as the function's implicit argument.
8342+
// On AVR, a return struct with size less than or equals to 8 bytes is
8343+
// returned directly via registers R18-R25. On AVRTiny, a return struct
8344+
// with size less than or equals to 4 bytes is returned directly via
8345+
// registers R22-R25.
8346+
if (isAggregateTypeForABI(Ty) &&
8347+
getContext().getTypeSize(Ty) <= RetRegs * 8)
8348+
return ABIArgInfo::getDirect();
8349+
// A return value (struct or scalar) with larger size is returned via a
8350+
// stack slot, along with a pointer as the function's implicit argument.
8351+
if (getContext().getTypeSize(Ty) > RetRegs * 8) {
83518352
LargeRet = true;
83528353
return getNaturalAlignIndirect(Ty);
83538354
}

clang/test/CodeGen/avr/struct.c renamed to clang/test/CodeGen/avr/return-value.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,22 @@ struct s04 foo04(int a, int b) {
3333
return a0;
3434
}
3535

36+
long long fooi64(void) {
37+
return 0xaa5533;
38+
}
39+
3640
// AVR: %struct.s10 = type { i16, i16, i16, i16, i16 }
3741
// AVR: %struct.s06 = type { i16, i16, i16 }
3842
// AVR: %struct.s04 = type { i16, i16 }
3943
// AVR: define{{.*}} void @foo10(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c)
4044
// AVR: define{{.*}} %struct.s06 @foo06(i16 noundef %a, i16 noundef %b, i16 noundef %c)
4145
// AVR: define{{.*}} %struct.s04 @foo04(i16 noundef %a, i16 noundef %b)
46+
// AVR: define{{.*}} i64 @fooi64()
4247

4348
// TINY: %struct.s10 = type { i16, i16, i16, i16, i16 }
4449
// TINY: %struct.s06 = type { i16, i16, i16 }
4550
// TINY: %struct.s04 = type { i16, i16 }
4651
// TINY: define{{.*}} void @foo10(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c)
4752
// TINY: define{{.*}} void @foo06(ptr {{.*}}, i16 noundef %a, i16 noundef %b, i16 noundef %c)
4853
// TINY: define{{.*}} %struct.s04 @foo04(i16 noundef %a, i16 noundef %b)
54+
// TINY: define{{.*}} void @fooi64(ptr {{.*}})

0 commit comments

Comments
 (0)