Skip to content

Commit cdcc5d4

Browse files
authored
[AVR] Set mayLoad/mayStore flags of some load/store instructions (#172986)
fixes llvm/llvm-project#156782
1 parent c2a8739 commit cdcc5d4

File tree

2 files changed

+79
-61
lines changed

2 files changed

+79
-61
lines changed

llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ bool AVRExpandPseudo::expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsELPM) {
873873
auto MIBLO = buildMI(MBB, MBBI, Opc);
874874
buildMI(MBB, MBBI, AVR::MOVRdRr)
875875
.addReg(DstLoReg, RegState::Define)
876-
.addReg(AVR::R0, RegState::Kill);
876+
.addReg(STI.getTmpRegister(), RegState::Kill);
877877
MIBLO.setMemRefs(MI.memoperands());
878878
// Increase the Z register by 1.
879879
if (STI.hasADDSUBIW()) {
@@ -901,7 +901,7 @@ bool AVRExpandPseudo::expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsELPM) {
901901
auto MIBHI = buildMI(MBB, MBBI, Opc);
902902
buildMI(MBB, MBBI, AVR::MOVRdRr)
903903
.addReg(DstHiReg, RegState::Define)
904-
.addReg(AVR::R0, RegState::Kill);
904+
.addReg(STI.getTmpRegister(), RegState::Kill);
905905
MIBHI.setMemRefs(MI.memoperands());
906906
}
907907

@@ -972,7 +972,7 @@ bool AVRExpandPseudo::expandLPMBELPMB(Block &MBB, BlockIt MBBI, bool IsELPM) {
972972
auto MILB = buildMI(MBB, MBBI, Opc);
973973
buildMI(MBB, MBBI, AVR::MOVRdRr)
974974
.addReg(DstReg, RegState::Define)
975-
.addReg(AVR::R0, RegState::Kill);
975+
.addReg(STI.getTmpRegister(), RegState::Kill);
976976
MILB.setMemRefs(MI.memoperands());
977977
}
978978

llvm/lib/Target/AVR/AVRInstrInfo.td

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,10 @@ let Defs = [SP, SREG], Uses = [SP] in {
352352
// register allocator might use it in rare cases (for rematerialization, it
353353
// seems). hasSideEffects needs to be set to true so this instruction isn't
354354
// considered dead.
355-
let Defs = [R31R30], hasSideEffects = 1 in def ADJCALLSTACKUP
356-
: Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
357-
"#ADJCALLSTACKUP", [(AVRcallseq_end timm:$amt1, timm:$amt2)]>;
355+
let Defs = [R31R30], hasSideEffects = 1 in
356+
def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
357+
"#ADJCALLSTACKUP",
358+
[(AVRcallseq_end timm:$amt1, timm:$amt2)]>;
358359
}
359360

360361
//===----------------------------------------------------------------------===//
@@ -874,7 +875,7 @@ let isReMaterializable = 1 in {
874875
}
875876

876877
// Load from data space into register.
877-
let canFoldAsLoad = 1, isReMaterializable = 1 in {
878+
let mayLoad = 1, isReMaterializable = 1 in {
878879
def LDSRdK : F32DM<0b0, (outs GPR8:$rd), (ins imm16:$k), "lds\t$rd, $k",
879880
[(set i8:$rd, (load imm:$k))]>,
880881
Requires<[HasSRAM, HasNonTinyEncoding]>;
@@ -895,7 +896,7 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
895896
}
896897

897898
// Indirect loads.
898-
let canFoldAsLoad = 1, isReMaterializable = 1 in {
899+
let mayLoad = 1, isReMaterializable = 1 in {
899900
def LDRdPtr : FSTLD<0, 0b00, (outs GPR8:$reg), (ins PTRREGS:$ptrreg),
900901
"ld\t$reg, $ptrreg",
901902
[(set GPR8:$reg, (load i16:$ptrreg))]>,
@@ -910,10 +911,11 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
910911
// ld Rd, P+
911912
// ld Rd+1, P+
912913
// subiw P, 2
913-
let Constraints = "@earlyclobber $reg" in def LDWRdPtr
914-
: Pseudo<(outs DREGS:$reg), (ins PTRDISPREGS:$ptrreg),
915-
"ldw\t$reg, $ptrreg", [(set i16:$reg, (load i16:$ptrreg))]>,
916-
Requires<[HasSRAM]>;
914+
let Constraints = "@earlyclobber $reg" in
915+
def LDWRdPtr : Pseudo<(outs DREGS:$reg), (ins PTRDISPREGS:$ptrreg),
916+
"ldw\t$reg, $ptrreg",
917+
[(set i16:$reg, (load i16:$ptrreg))]>,
918+
Requires<[HasSRAM]>;
917919
}
918920

919921
// Indirect loads (with postincrement or predecrement).
@@ -946,7 +948,7 @@ let mayLoad = 1, hasSideEffects = 0,
946948
}
947949

948950
// Load indirect with displacement operations.
949-
let canFoldAsLoad = 1, isReMaterializable = 1 in {
951+
let mayLoad = 1, isReMaterializable = 1 in {
950952
def LDDRdPtrQ : FSTDLDD<0, (outs GPR8:$reg), (ins memri:$memri),
951953
"ldd\t$reg, $memri",
952954
[(set i8:$reg, (load addr:$memri))]>,
@@ -984,20 +986,23 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
984986
// The pseudo expansion pass trivially expands this into LDDWRdPtrQ.
985987
//
986988
// This instruction may be removed once PR13375 is fixed.
987-
let mayLoad = 1, hasSideEffects = 0 in
989+
let hasSideEffects = 0 in
988990
def LDDWRdYQ : Pseudo<(outs DREGS:$dst), (ins memri:$memri),
989991
"lddw\t$dst, $memri", []>,
990992
Requires<[HasSRAM]>;
991993
}
992994

995+
let mayLoad = 1, isReMaterializable = 1 in
993996
class AtomicLoad<PatFrag Op, RegisterClass DRC, RegisterClass PTRRC>
994997
: Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
995998
[(set DRC:$rd, (Op i16:$rr))]>;
996999

1000+
let mayStore = 1 in
9971001
class AtomicStore<PatFrag Op, RegisterClass DRC, RegisterClass PTRRC>
9981002
: Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op",
9991003
[(Op DRC:$rr, i16:$rd)]>;
10001004

1005+
let mayLoad = 1, mayStore = 1 in
10011006
class AtomicLoadOp<PatFrag Op, RegisterClass DRC, RegisterClass PTRRC>
10021007
: Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand), "atomic_op",
10031008
[(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>;
@@ -1037,27 +1042,31 @@ def AtomicFence
10371042
: Pseudo<(outs), (ins), "atomic_fence", [(atomic_fence timm, timm)]>;
10381043

10391044
// Indirect store from register to data space.
1040-
def STSKRr : F32DM<0b1, (outs), (ins imm16:$k, GPR8:$rd), "sts\t$k, $rd",
1041-
[(store i8:$rd, imm:$k)]>,
1042-
Requires<[HasSRAM, HasNonTinyEncoding]>;
1045+
let mayStore = 1 in {
1046+
def STSKRr : F32DM<0b1, (outs), (ins imm16:$k, GPR8:$rd), "sts\t$k, $rd",
1047+
[(store i8:$rd, imm:$k)]>,
1048+
Requires<[HasSRAM, HasNonTinyEncoding]>;
10431049

1044-
// Store from register to data space, which is only available on AVRTiny.
1045-
def STSKRrTiny : FLDSSTSTINY<0b1, (outs), (ins imm7tiny:$k, LD8:$rd),
1046-
"sts\t$k, $rd", [(store i8:$rd, imm:$k)]>,
1047-
Requires<[HasSRAM, HasTinyEncoding]>;
1050+
// Store from register to data space, which is only available on AVRTiny.
1051+
def STSKRrTiny : FLDSSTSTINY<0b1, (outs), (ins imm7tiny:$k, LD8:$rd),
1052+
"sts\t$k, $rd", [(store i8:$rd, imm:$k)]>,
1053+
Requires<[HasSRAM, HasTinyEncoding]>;
1054+
}
10481055

10491056
// STSW K+1:K, Rr+1:Rr
10501057
//
10511058
// Expands to:
10521059
// sts Rr+1, (K+1:K) + 1
10531060
// sts Rr, (K+1:K)
1061+
let mayStore = 1 in
10541062
def STSWKRr : Pseudo<(outs), (ins i16imm:$dst, DREGS:$src),
10551063
"stsw\t$dst, $src", [(store i16:$src, imm:$dst)]>,
10561064
Requires<[HasSRAM, HasNonTinyEncoding]>;
10571065

10581066
// Indirect stores.
10591067
// ST P, Rr
10601068
// Stores the value of Rr into the location addressed by pointer P.
1069+
let mayStore = 1 in
10611070
def STPtrRr : FSTLD<1, 0b00, (outs), (ins PTRREGS:$ptrreg, GPR8:$reg),
10621071
"st\t$ptrreg, $reg", [(store GPR8:$reg, i16:$ptrreg)]>,
10631072
Requires<[HasSRAM]>;
@@ -1072,12 +1081,13 @@ def STPtrRr : FSTLD<1, 0b00, (outs), (ins PTRREGS:$ptrreg, GPR8:$reg),
10721081
// st P+, Rr
10731082
// st P+, Rr+1
10741083
// subiw P, q+2
1084+
let mayStore = 1 in
10751085
def STWPtrRr : Pseudo<(outs), (ins PTRDISPREGS:$ptrreg, DREGS:$reg),
10761086
"stw\t$ptrreg, $reg", [(store i16:$reg, i16:$ptrreg)]>,
10771087
Requires<[HasSRAM]>;
10781088

10791089
// Indirect stores (with postincrement or predecrement).
1080-
let Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in {
1090+
let mayStore = 1, Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in {
10811091

10821092
// ST P+, Rr
10831093
// Stores the value of Rr into the location addressed by pointer P.
@@ -1133,6 +1143,7 @@ let Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in {
11331143
// STD P+q, Rr
11341144
// Stores the value of Rr into the location addressed by pointer P with a
11351145
// displacement of q. Does not modify P.
1146+
let mayStore = 1 in
11361147
def STDPtrQRr : FSTDLDD<1, (outs), (ins memri:$memri, GPR8:$reg),
11371148
"std\t$memri, $reg", [(store i8:$reg, addr:$memri)]>,
11381149
Requires<[HasSRAM, HasNonTinyEncoding]>;
@@ -1149,17 +1160,16 @@ def STDPtrQRr : FSTDLDD<1, (outs), (ins memri:$memri, GPR8:$reg),
11491160
// st P+, Rr
11501161
// st P+, Rr+1
11511162
// subiw P, q+2
1163+
let mayStore = 1 in
11521164
def STDWPtrQRr : Pseudo<(outs), (ins memri:$memri, DREGS:$src),
11531165
"stdw\t$memri, $src", [(store i16:$src, addr:$memri)]>,
11541166
Requires<[HasSRAM]>;
11551167

11561168
// Load program memory operations.
1157-
let canFoldAsLoad = 1, isReMaterializable = 1, mayLoad = 1,
1158-
hasSideEffects = 0 in {
1159-
let Defs = [R0],
1160-
Uses = [R31R30] in def LPM
1161-
: F16<0b1001010111001000, (outs), (ins), "lpm", []>,
1162-
Requires<[HasLPM]>;
1169+
let isReMaterializable = 1, mayLoad = 1, hasSideEffects = 0 in {
1170+
let Defs = [R0], Uses = [R31R30] in
1171+
def LPM : F16<0b1001010111001000, (outs), (ins), "lpm", []>,
1172+
Requires<[HasLPM]>;
11631173

11641174
// These pseudo instructions are combination of the OUT and LPM instructions.
11651175
let Defs = [R0] in {
@@ -1173,7 +1183,9 @@ let canFoldAsLoad = 1, isReMaterializable = 1, mayLoad = 1,
11731183

11741184
def LPMRdZ : FLPMX<0, 0, (outs GPR8:$rd), (ins ZREG:$z), "lpm\t$rd, $z", []>,
11751185
Requires<[HasLPMX]>;
1186+
}
11761187

1188+
let mayLoad = 1, hasSideEffects = 0 in {
11771189
// Load program memory, while postincrementing the Z register.
11781190
let Defs = [R31R30] in {
11791191
def LPMRdZPi : FLPMX<0, 1, (outs GPR8:$rd), (ins ZREG:$z),
@@ -1202,7 +1214,7 @@ let mayLoad = 1, hasSideEffects = 0 in {
12021214
Requires<[HasELPMX]>;
12031215

12041216
// These pseudo instructions are combination of the OUT and ELPM instructions.
1205-
let Defs = [R0] in {
1217+
let Defs = [R0], mayStore = 1 in {
12061218
def ELPMBRdZ : Pseudo<(outs GPR8:$dst), (ins ZREG:$z, LD8:$p),
12071219
"elpmb\t$dst, $z, $p", []>,
12081220
Requires<[HasELPM]>;
@@ -1226,8 +1238,8 @@ let mayLoad = 1, hasSideEffects = 0 in {
12261238
}
12271239

12281240
// Store program memory operations.
1229-
let Uses = [R1, R0] in {
1230-
let Uses = [R31R30, R1, R0] in
1241+
let Uses = [R1, R0], mayStore = 1 in {
1242+
let Uses = [R31R30] in
12311243
def SPM : F16<0b1001010111101000, (outs), (ins), "spm", []>,
12321244
Requires<[HasSPM]>;
12331245

@@ -1239,7 +1251,7 @@ let Uses = [R1, R0] in {
12391251
}
12401252

12411253
// Read data from IO location operations.
1242-
let canFoldAsLoad = 1, isReMaterializable = 1 in {
1254+
let mayLoad = 1 in {
12431255
def INRdA : FIORdA<(outs GPR8:$rd), (ins imm_port6:$A), "in\t$rd, $A",
12441256
[(set i8:$rd, (load ioaddr8:$A))]>;
12451257

@@ -1248,11 +1260,13 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
12481260
}
12491261

12501262
// Write data to IO location operations.
1251-
def OUTARr : FIOARr<(outs), (ins imm_port6:$A, GPR8:$rr), "out\t$A, $rr",
1252-
[(store i8:$rr, ioaddr8:$A)]>;
1263+
let mayStore = 1 in {
1264+
def OUTARr : FIOARr<(outs), (ins imm_port6:$A, GPR8:$rr), "out\t$A, $rr",
1265+
[(store i8:$rr, ioaddr8:$A)]>;
12531266

1254-
def OUTWARr : Pseudo<(outs), (ins imm_port6:$dst, DREGS:$src),
1255-
"outw\t$dst, $src", [(store i16:$src, ioaddr16:$dst)]>;
1267+
def OUTWARr : Pseudo<(outs), (ins imm_port6:$dst, DREGS:$src),
1268+
"outw\t$dst, $src", [(store i16:$src, ioaddr16:$dst)]>;
1269+
}
12561270

12571271
// Stack push/pop operations.
12581272
let Defs = [SP], Uses = [SP], hasSideEffects = 0 in {
@@ -1277,17 +1291,19 @@ let Defs = [SP], Uses = [SP], hasSideEffects = 0 in {
12771291
}
12781292

12791293
// Read-Write-Modify (RMW) instructions.
1280-
def XCHZRd : FZRd<0b100, (outs GPR8:$rd), (ins ZREG:$z), "xch\t$z, $rd", []>,
1281-
Requires<[SupportsRMW]>;
1294+
let mayLoad = 1, mayStore = 1 in {
1295+
def XCHZRd : FZRd<0b100, (outs GPR8:$rd), (ins ZREG:$z), "xch\t$z, $rd", []>,
1296+
Requires<[SupportsRMW]>;
12821297

1283-
def LASZRd : FZRd<0b101, (outs GPR8:$rd), (ins ZREG:$z), "las\t$z, $rd", []>,
1284-
Requires<[SupportsRMW]>;
1298+
def LASZRd : FZRd<0b101, (outs GPR8:$rd), (ins ZREG:$z), "las\t$z, $rd", []>,
1299+
Requires<[SupportsRMW]>;
12851300

1286-
def LACZRd : FZRd<0b110, (outs GPR8:$rd), (ins ZREG:$z), "lac\t$z, $rd", []>,
1287-
Requires<[SupportsRMW]>;
1301+
def LACZRd : FZRd<0b110, (outs GPR8:$rd), (ins ZREG:$z), "lac\t$z, $rd", []>,
1302+
Requires<[SupportsRMW]>;
12881303

1289-
def LATZRd : FZRd<0b111, (outs GPR8:$rd), (ins ZREG:$z), "lat\t$z, $rd", []>,
1290-
Requires<[SupportsRMW]>;
1304+
def LATZRd : FZRd<0b111, (outs GPR8:$rd), (ins ZREG:$z), "lat\t$z, $rd", []>,
1305+
Requires<[SupportsRMW]>;
1306+
}
12911307

12921308
//===----------------------------------------------------------------------===//
12931309
// Bit and bit-test instructions
@@ -1380,21 +1396,23 @@ def SWAPRd : FRd<0b1001, 0b0100010, (outs GPR8:$rd), (ins GPR8:$src),
13801396
// IO register bit set/clear operations.
13811397
//: TODO: add patterns when popcount(imm)==2 to be expanded with 2 sbi/cbi
13821398
// instead of in+ori+out which requires one more instr.
1383-
def SBIAb : FIOBIT<0b10, (outs), (ins imm_port5:$addr, i8imm:$b),
1384-
"sbi\t$addr, $b",
1385-
[(store(or(i8(load lowioaddr8:$addr)), iobitpos8:$b),
1386-
lowioaddr8:$addr)]>;
1387-
1388-
def CBIAb : FIOBIT<0b00, (outs), (ins imm_port5:$addr, i8imm :$b),
1389-
"cbi\t$addr, $b",
1390-
[(store(and(i8(load lowioaddr8:$addr)), iobitposn8:$b),
1391-
lowioaddr8:$addr)]>;
1399+
let mayStore = 1 in {
1400+
def SBIAb : FIOBIT<0b10, (outs), (ins imm_port5:$addr, i8imm:$b),
1401+
"sbi\t$addr, $b",
1402+
[(store(or(i8(load lowioaddr8:$addr)), iobitpos8:$b),
1403+
lowioaddr8:$addr)]>;
1404+
1405+
def CBIAb : FIOBIT<0b00, (outs), (ins imm_port5:$addr, i8imm :$b),
1406+
"cbi\t$addr, $b",
1407+
[(store(and(i8(load lowioaddr8:$addr)), iobitposn8:$b),
1408+
lowioaddr8:$addr)]>;
1409+
}
13921410

13931411
// Status register bit load/store operations.
1394-
let Defs = [SREG] in
1412+
let Defs = [SREG], hasSideEffects = 1 in
13951413
def BST : FRdB<0b01, (outs), (ins GPR8:$rd, i8imm:$b), "bst\t$rd, $b", []>;
13961414

1397-
let Constraints = "$src = $rd", Uses = [SREG] in
1415+
let Constraints = "$src = $rd", Uses = [SREG], hasSideEffects = 0 in
13981416
def BLD : FRdB<0b00, (outs GPR8:$rd), (ins GPR8:$src, i8imm:$b), "bld\t$rd, $b",
13991417
[]>;
14001418

@@ -1420,7 +1438,7 @@ def ROL : InstAlias<"rol\t$rd", (ADCRdRr GPR8 : $rd, GPR8 : $rd)>;
14201438
// Sets all bits in a register.
14211439
def : InstAlias<"ser\t$rd", (LDIRdK LD8 : $rd, 0xff), 0>;
14221440

1423-
let hasSideEffects=1 in {
1441+
let hasSideEffects = 1 in {
14241442
let Defs = [SREG] in def BSETs : FS<0, (outs), (ins i8imm:$s), "bset\t$s", []>;
14251443
let Defs = [SREG] in def BCLRs : FS<1, (outs), (ins i8imm:$s), "bclr\t$s", []>;
14261444
}
@@ -1515,23 +1533,23 @@ def FRMIDX : Pseudo<(outs DLDREGS:$dst), (ins DLDREGS:$src, i16imm:$src2),
15151533
// the Z register removed, as the source/input to these instructions.
15161534
// This pseudo is either converted to a regular store or a push which clobbers
15171535
// SP.
1518-
let Defs = [SP], Uses = [SP], hasSideEffects = 0 in
1536+
let Defs = [SP], Uses = [SP], hasSideEffects = 0, mayStore = 1 in
15191537
def STDSPQRr : StorePseudo<(outs), (ins memspi:$dst, GPR8NOZ:$src),
15201538
"stdstk\t$dst, $src", [(store i8:$src, addr:$dst)]>;
15211539

15221540
// See the comment on STDSPQRr.
15231541
// This pseudo is either converted to a regular store or a push which clobbers
15241542
// SP.
1525-
let Defs = [SP], Uses = [SP], hasSideEffects = 0 in
1543+
let Defs = [SP], Uses = [SP], hasSideEffects = 0, mayStore = 1 in
15261544
def STDWSPQRr : StorePseudo<(outs), (ins memspi:$dt, DREGSNOZ:$src),
15271545
"stdwstk\t$dt, $src", [(store i16:$src, addr:$dt)]>;
15281546

15291547
// SP read/write pseudos.
1530-
let hasSideEffects = 0 in {
1531-
let Uses = [SP] in
1548+
let hasSideEffects = 0 in {
1549+
let Uses = [SP], mayLoad = 1 in
15321550
def SPREAD : Pseudo<(outs DREGS:$dst), (ins GPRSP:$src), "spread\t$dst, $src",
15331551
[]>;
1534-
let Defs = [SP] in
1552+
let Defs = [SP], mayStore = 1 in
15351553
def SPWRITE : Pseudo<(outs GPRSP:$dst), (ins DREGS:$src),
15361554
"spwrite\t$dst, $src", []>;
15371555
}

0 commit comments

Comments
 (0)