llvm-project
llvm-project copied to clipboard
[AVR] illegal "LPM Rx, Z+" is generated on avr2 family devices
LPMX is not avaliable on avr2, but for the following C code
void foo(int *p, int a) {
static __flash const int arr[] = {123, 234, 456, 67};
p[0] = arr[a];
}
Build it with command
clang a.c -O3 -Wall --target=avr -mmcu=at90s8515 -S
The following assembly is generated
foo: ; @foo
; %bb.0: ; %entry
lsl r22
rol r23
subi r22, -lo8(foo.arr)
sbci r23, -hi8(foo.arr)
mov r30, r22
mov r31, r23
lpm r18, Z+
lpm r19, Z
mov r30, r24
mov r31, r25
st Z, r18
std Z+1, r19
ret
However the lpm r19, Z
belongs to feature LPMX and is illegal on AVR2 family.
the LPM and ELPM instructions (in which R0 is the implicit destination) should be selected.
The following devices are affected
def : Device<"at90s2313", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2323", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2333", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2343", FamilyAVR2, ELFArchAVR2>;
def : Device<"attiny22", FamilyAVR2, ELFArchAVR2>;
def : Device<"attiny26", FamilyAVR2, ELFArchAVR2, [FeatureLPMX]>;
def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25, [FeatureMOVW, FeatureLPMX]>;
def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>;
After https://reviews.llvm.org/D131844,
AVRExpandPseudo::expandLPMWELPMW
is the only user of AVRExpandPseudo::scavengeGPR8
, we need to check if we can eliminate that.
fixed by https://github.com/llvm/llvm-project/commit/4fa9dc948226e374372537250d046924d348307e https://github.com/llvm/llvm-project/commit/2a6e39dbf84af4b3f8b31930fed786b3c56287f5 https://github.com/llvm/llvm-project/commit/acb4d143bdb75930eae8dc700e16e4950b8cc2c8