Skip to content

Commit d94d079

Browse files
author
Diogo Sampaio
committed
[ARM][Thumb2] Fix ADD/SUB invalid writes to SP
Summary: This patch fixes pr23772 [ARM] r226200 can emit illegal thumb2 instruction: "sub sp, r12, llvm#80". The violation was that SUB and ADD (reg, immediate) instructions can only write to SP if the source register is also SP. So the above instructions was unpredictable. To enforce that the instruction t2(ADD|SUB)ri does not write to SP we now enforce the destination register to be rGPR (That exclude PC and SP). Different than the ARM specification, that defines one instruction that can read from SP, and one that can't, here we inserted one that can't write to SP, and other that can only write to SP as to reuse most of the hard-coded size optimizations. When performing this change, it uncovered that emitting Thumb2 Reg plus Immediate could not emit all variants of ADD SP, SP #imm instructions before so it was refactored to be able to. (see test/CodeGen/Thumb2/mve-stacksplot.mir where we use a subw sp, sp, Imm12 variant ) It also uncovered a disassembly issue of adr.w instructions, that were only written as SUBW instructions (see llvm/test/MC/Disassembler/ARM/thumb2.txt). Reviewers: eli.friedman, dmgreen, carwil, olista01, efriedma, andreadb Reviewed By: efriedma Subscribers: gbedwell, john.brawn, efriedma, ostannard, kristof.beyls, hiraditya, dmgreen, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70680
1 parent fd42a4a commit d94d079

26 files changed

+749
-148
lines changed

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1171,11 +1171,15 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
11711171
case ARM::ADDri:
11721172
case ARM::t2ADDri:
11731173
case ARM::t2ADDri12:
1174+
case ARM::t2ADDspImm:
1175+
case ARM::t2ADDspImm12:
11741176
Offset = -MI->getOperand(2).getImm();
11751177
break;
11761178
case ARM::SUBri:
11771179
case ARM::t2SUBri:
11781180
case ARM::t2SUBri12:
1181+
case ARM::t2SUBspImm:
1182+
case ARM::t2SUBspImm12:
11791183
Offset = MI->getOperand(2).getImm();
11801184
break;
11811185
case ARM::tSUBspi:

llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp

+21-4
Original file line numberDiff line numberDiff line change
@@ -3257,22 +3257,26 @@ bool ARMBaseInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
32573257
}
32583258
break;
32593259
case ARM::t2ADDrr:
3260-
case ARM::t2SUBrr:
3260+
case ARM::t2SUBrr: {
32613261
if (UseOpc == ARM::t2SUBrr && Commute)
32623262
return false;
32633263

32643264
// ADD/SUB are special because they're essentially the same operation, so
32653265
// we can handle a larger range of immediates.
3266+
const bool ToSP = DefMI.getOperand(0).getReg() == ARM::SP;
3267+
const unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
3268+
const unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
32663269
if (ARM_AM::isT2SOImmTwoPartVal(ImmVal))
3267-
NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2ADDri : ARM::t2SUBri;
3270+
NewUseOpc = UseOpc == ARM::t2ADDrr ? t2ADD : t2SUB;
32683271
else if (ARM_AM::isT2SOImmTwoPartVal(-ImmVal)) {
32693272
ImmVal = -ImmVal;
3270-
NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2SUBri : ARM::t2ADDri;
3273+
NewUseOpc = UseOpc == ARM::t2ADDrr ? t2SUB : t2ADD;
32713274
} else
32723275
return false;
32733276
SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
32743277
SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
32753278
break;
3279+
}
32763280
case ARM::t2ORRrr:
32773281
case ARM::t2EORrr:
32783282
if (!ARM_AM::isT2SOImmTwoPartVal(ImmVal))
@@ -3292,7 +3296,8 @@ bool ARMBaseInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
32923296
unsigned OpIdx = Commute ? 2 : 1;
32933297
Register Reg1 = UseMI.getOperand(OpIdx).getReg();
32943298
bool isKill = UseMI.getOperand(OpIdx).isKill();
3295-
Register NewReg = MRI->createVirtualRegister(MRI->getRegClass(Reg));
3299+
const TargetRegisterClass *TRC = MRI->getRegClass(Reg);
3300+
Register NewReg = MRI->createVirtualRegister(TRC);
32963301
BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc),
32973302
NewReg)
32983303
.addReg(Reg1, getKillRegState(isKill))
@@ -3304,6 +3309,18 @@ bool ARMBaseInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
33043309
UseMI.getOperand(1).setIsKill();
33053310
UseMI.getOperand(2).ChangeToImmediate(SOImmValV2);
33063311
DefMI.eraseFromParent();
3312+
// FIXME: t2ADDrr should be split, as different rulles apply when writing to SP.
3313+
// Just as t2ADDri, that was split to [t2ADDri, t2ADDspImm].
3314+
// Then the below code will not be needed, as the input/output register
3315+
// classes will be rgpr or gprSP.
3316+
// For now, we fix the UseMI operand explicitly here:
3317+
switch(NewUseOpc){
3318+
case ARM::t2ADDspImm:
3319+
case ARM::t2SUBspImm:
3320+
case ARM::t2ADDri:
3321+
case ARM::t2SUBri:
3322+
MRI->setRegClass(UseMI.getOperand(0).getReg(), TRC);
3323+
}
33073324
return true;
33083325
}
33093326

llvm/lib/Target/ARM/ARMInstrThumb2.td

+154-39
Original file line numberDiff line numberDiff line change
@@ -918,10 +918,26 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, SDNode opnode,
918918
// The register-immediate version is re-materializable. This is useful
919919
// in particular for taking the address of a local.
920920
let isReMaterializable = 1 in {
921+
def spImm : T2sTwoRegImm<
922+
(outs GPRsp:$Rd), (ins GPRsp:$Rn, t2_so_imm:$imm), IIC_iALUi,
923+
opc, ".w\t$Rd, $Rn, $imm",
924+
[]>,
925+
Sched<[WriteALU, ReadALU]> {
926+
let Rn = 13;
927+
let Rd = 13;
928+
929+
let Inst{31-27} = 0b11110;
930+
let Inst{25-24} = 0b01;
931+
let Inst{23-21} = op23_21;
932+
let Inst{15} = 0;
933+
934+
let DecoderMethod = "DecodeT2AddSubSPImm";
935+
}
936+
921937
def ri : T2sTwoRegImm<
922-
(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi,
938+
(outs rGPR:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi,
923939
opc, ".w\t$Rd, $Rn, $imm",
924-
[(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>,
940+
[(set rGPR:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>,
925941
Sched<[WriteALU, ReadALU]> {
926942
let Inst{31-27} = 0b11110;
927943
let Inst{25} = 0;
@@ -932,9 +948,9 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, SDNode opnode,
932948
}
933949
// 12-bit imm
934950
def ri12 : T2I<
935-
(outs GPRnopc:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
951+
(outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
936952
!strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
937-
[(set GPRnopc:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>,
953+
[(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>,
938954
Sched<[WriteALU, ReadALU]> {
939955
bits<4> Rd;
940956
bits<4> Rn;
@@ -950,6 +966,26 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, SDNode opnode,
950966
let Inst{11-8} = Rd;
951967
let Inst{7-0} = imm{7-0};
952968
}
969+
def spImm12 : T2I<
970+
(outs GPRsp:$Rd), (ins GPRsp:$Rn, imm0_4095:$imm), IIC_iALUi,
971+
!strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
972+
[]>,
973+
Sched<[WriteALU, ReadALU]> {
974+
bits<4> Rd = 13;
975+
bits<4> Rn = 13;
976+
bits<12> imm;
977+
let Inst{31-27} = 0b11110;
978+
let Inst{26} = imm{11};
979+
let Inst{25-24} = 0b10;
980+
let Inst{23-21} = op23_21;
981+
let Inst{20} = 0; // The S bit.
982+
let Inst{19-16} = Rn;
983+
let Inst{15} = 0;
984+
let Inst{14-12} = imm{10-8};
985+
let Inst{11-8} = Rd;
986+
let Inst{7-0} = imm{7-0};
987+
let DecoderMethod = "DecodeT2AddSubSPImm";
988+
}
953989
// register
954990
def rr : T2sThreeReg<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm),
955991
IIC_iALUr, opc, ".w\t$Rd, $Rn, $Rm",
@@ -2267,19 +2303,29 @@ def : t2InstSubst<"sbc${s}${p} $rd, $rn, $imm",
22672303
(t2ADCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>;
22682304

22692305
def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm",
2270-
(t2SUBri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2271-
def : t2InstSubst<"addw${p} $rd, $rn, $imm",
2272-
(t2SUBri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
2306+
(t2SUBri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
22732307
def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
2274-
(t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2275-
def : t2InstSubst<"subw${p} $rd, $rn, $imm",
2276-
(t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
2308+
(t2ADDri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
22772309
def : t2InstSubst<"subw${p} $Rd, $Rn, $imm",
2278-
(t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
2310+
(t2ADDri12 rGPR:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
22792311
def : t2InstSubst<"sub${s}${p} $rd, $rn, $imm",
2280-
(t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2312+
(t2ADDri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
22812313
def : t2InstSubst<"sub${p} $rd, $rn, $imm",
2282-
(t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
2314+
(t2ADDri12 rGPR:$rd, GPR:$rn, imm0_4095_neg:$imm, pred:$p)>;
2315+
2316+
// SP to SP alike
2317+
def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm",
2318+
(t2SUBspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2319+
def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
2320+
(t2ADDspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2321+
def : t2InstSubst<"subw${p} $Rd, $Rn, $imm",
2322+
(t2ADDspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
2323+
def : t2InstSubst<"sub${s}${p} $rd, $rn, $imm",
2324+
(t2ADDspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2325+
def : t2InstSubst<"sub${p} $rd, $rn, $imm",
2326+
(t2ADDspImm12 GPRsp:$rd, GPRsp:$rn, imm0_4095_neg:$imm, pred:$p)>;
2327+
2328+
22832329
// RSB
22842330
defm t2RSB : T2I_rbin_irs <0b1110, "rsb", sub>;
22852331

@@ -2295,12 +2341,12 @@ defm t2RSBS : T2I_rbin_s_is <ARMsubc>;
22952341
// The AddedComplexity preferences the first variant over the others since
22962342
// it can be shrunk to a 16-bit wide encoding, while the others cannot.
22972343
let AddedComplexity = 1 in
2298-
def : T2Pat<(add GPR:$src, imm1_255_neg:$imm),
2299-
(t2SUBri GPR:$src, imm1_255_neg:$imm)>;
2300-
def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
2301-
(t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
2302-
def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
2303-
(t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
2344+
def : T2Pat<(add rGPR:$src, imm1_255_neg:$imm),
2345+
(t2SUBri rGPR:$src, imm1_255_neg:$imm)>;
2346+
def : T2Pat<(add rGPR:$src, t2_so_imm_neg:$imm),
2347+
(t2SUBri rGPR:$src, t2_so_imm_neg:$imm)>;
2348+
def : T2Pat<(add rGPR:$src, imm0_4095_neg:$imm),
2349+
(t2SUBri12 rGPR:$src, imm0_4095_neg:$imm)>;
23042350
def : T2Pat<(add GPR:$src, imm0_65535_neg:$imm),
23052351
(t2SUBrr GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>;
23062352

@@ -2799,10 +2845,10 @@ def : T2Pat<(t2_so_imm_not:$src),
27992845
// Thumb2SizeReduction's chances later on we select a t2ADD for an or where
28002846
// possible.
28012847
def : T2Pat<(or AddLikeOrOp:$Rn, t2_so_imm:$imm),
2802-
(t2ADDri $Rn, t2_so_imm:$imm)>;
2848+
(t2ADDri rGPR:$Rn, t2_so_imm:$imm)>;
28032849

28042850
def : T2Pat<(or AddLikeOrOp:$Rn, imm0_4095:$Rm),
2805-
(t2ADDri12 $Rn, imm0_4095:$Rm)>;
2851+
(t2ADDri12 rGPR:$Rn, imm0_4095:$Rm)>;
28062852

28072853
def : T2Pat<(or AddLikeOrOp:$Rn, non_imm32:$Rm),
28082854
(t2ADDrr $Rn, $Rm)>;
@@ -4666,20 +4712,22 @@ def : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $ShiftedRm",
46664712

46674713
// Aliases for ADD without the ".w" optional width specifier.
46684714
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4669-
(t2ADDri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p,
4715+
(t2ADDri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p,
46704716
cc_out:$s)>;
46714717
def : t2InstAlias<"add${p} $Rd, $Rn, $imm",
4672-
(t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
4718+
(t2ADDri12 rGPR:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
46734719
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $Rm",
46744720
(t2ADDrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
46754721
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm",
46764722
(t2ADDrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm,
46774723
pred:$p, cc_out:$s)>;
46784724
// ... and with the destination and source register combined.
46794725
def : t2InstAlias<"add${s}${p} $Rdn, $imm",
4680-
(t2ADDri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4726+
(t2ADDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
46814727
def : t2InstAlias<"add${p} $Rdn, $imm",
4682-
(t2ADDri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
4728+
(t2ADDri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
4729+
def : t2InstAlias<"addw${p} $Rdn, $imm",
4730+
(t2ADDri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
46834731
def : t2InstAlias<"add${s}${p} $Rdn, $Rm",
46844732
(t2ADDrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
46854733
def : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm",
@@ -4688,43 +4736,45 @@ def : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm",
46884736

46894737
// add w/ negative immediates is just a sub.
46904738
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
4691-
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
4739+
(t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
46924740
cc_out:$s)>;
46934741
def : t2InstSubst<"add${p} $Rd, $Rn, $imm",
4694-
(t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4742+
(t2SUBri12 rGPR:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
46954743
def : t2InstSubst<"add${s}${p} $Rdn, $imm",
4696-
(t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4744+
(t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_neg:$imm, pred:$p,
46974745
cc_out:$s)>;
46984746
def : t2InstSubst<"add${p} $Rdn, $imm",
4699-
(t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4747+
(t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
47004748

47014749
def : t2InstSubst<"add${s}${p}.w $Rd, $Rn, $imm",
4702-
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
4750+
(t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
47034751
cc_out:$s)>;
47044752
def : t2InstSubst<"addw${p} $Rd, $Rn, $imm",
4705-
(t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4753+
(t2SUBri12 rGPR:$Rd, rGPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
47064754
def : t2InstSubst<"add${s}${p}.w $Rdn, $imm",
4707-
(t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4755+
(t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_neg:$imm, pred:$p,
47084756
cc_out:$s)>;
47094757
def : t2InstSubst<"addw${p} $Rdn, $imm",
4710-
(t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4758+
(t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
47114759

47124760

47134761
// Aliases for SUB without the ".w" optional width specifier.
47144762
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm",
4715-
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4763+
(t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
47164764
def : t2InstAlias<"sub${p} $Rd, $Rn, $imm",
4717-
(t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
4765+
(t2SUBri12 rGPR:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
47184766
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm",
47194767
(t2SUBrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
47204768
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm",
47214769
(t2SUBrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm,
47224770
pred:$p, cc_out:$s)>;
47234771
// ... and with the destination and source register combined.
47244772
def : t2InstAlias<"sub${s}${p} $Rdn, $imm",
4725-
(t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4773+
(t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
47264774
def : t2InstAlias<"sub${p} $Rdn, $imm",
4727-
(t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
4775+
(t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
4776+
def : t2InstAlias<"subw${p} $Rdn, $imm",
4777+
(t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
47284778
def : t2InstAlias<"sub${s}${p}.w $Rdn, $Rm",
47294779
(t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
47304780
def : t2InstAlias<"sub${s}${p} $Rdn, $Rm",
@@ -4733,6 +4783,65 @@ def : t2InstAlias<"sub${s}${p} $Rdn, $ShiftedRm",
47334783
(t2SUBrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm,
47344784
pred:$p, cc_out:$s)>;
47354785

4786+
// SP to SP alike aliases
4787+
// Aliases for ADD without the ".w" optional width specifier.
4788+
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4789+
(t2ADDspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm:$imm, pred:$p,
4790+
cc_out:$s)>;
4791+
def : t2InstAlias<"add${p} $Rd, $Rn, $imm",
4792+
(t2ADDspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095:$imm, pred:$p)>;
4793+
// ... and with the destination and source register combined.
4794+
def : t2InstAlias<"add${s}${p} $Rdn, $imm",
4795+
(t2ADDspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4796+
4797+
def : t2InstAlias<"add${s}${p}.w $Rdn, $imm",
4798+
(t2ADDspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4799+
4800+
def : t2InstAlias<"add${p} $Rdn, $imm",
4801+
(t2ADDspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
4802+
4803+
def : t2InstAlias<"addw${p} $Rdn, $imm",
4804+
(t2ADDspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
4805+
4806+
// add w/ negative immediates is just a sub.
4807+
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
4808+
(t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm, pred:$p,
4809+
cc_out:$s)>;
4810+
def : t2InstSubst<"add${p} $Rd, $Rn, $imm",
4811+
(t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4812+
def : t2InstSubst<"add${s}${p} $Rdn, $imm",
4813+
(t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4814+
cc_out:$s)>;
4815+
def : t2InstSubst<"add${p} $Rdn, $imm",
4816+
(t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4817+
4818+
def : t2InstSubst<"add${s}${p}.w $Rd, $Rn, $imm",
4819+
(t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm, pred:$p,
4820+
cc_out:$s)>;
4821+
def : t2InstSubst<"addw${p} $Rd, $Rn, $imm",
4822+
(t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4823+
def : t2InstSubst<"add${s}${p}.w $Rdn, $imm",
4824+
(t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm_neg:$imm, pred:$p,
4825+
cc_out:$s)>;
4826+
def : t2InstSubst<"addw${p} $Rdn, $imm",
4827+
(t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
4828+
4829+
4830+
// Aliases for SUB without the ".w" optional width specifier.
4831+
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm",
4832+
(t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4833+
def : t2InstAlias<"sub${p} $Rd, $Rn, $imm",
4834+
(t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095:$imm, pred:$p)>;
4835+
// ... and with the destination and source register combined.
4836+
def : t2InstAlias<"sub${s}${p} $Rdn, $imm",
4837+
(t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4838+
def : t2InstAlias<"sub${s}${p}.w $Rdn, $imm",
4839+
(t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
4840+
def : t2InstAlias<"sub${p} $Rdn, $imm",
4841+
(t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
4842+
def : t2InstAlias<"subw${p} $Rdn, $imm",
4843+
(t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
4844+
47364845
// Alias for compares without the ".w" optional width specifier.
47374846
def : t2InstAlias<"cmn${p} $Rn, $Rm",
47384847
(t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
@@ -4989,10 +5098,16 @@ def : t2InstSubst<"orr${s}${p} $Rdn, $imm",
49895098
pred:$p, cc_out:$s)>;
49905099
// Likewise, "add Rd, t2_so_imm_neg" -> sub
49915100
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
4992-
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
5101+
(t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
5102+
pred:$p, cc_out:$s)>;
5103+
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
5104+
(t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm,
5105+
pred:$p, cc_out:$s)>;
5106+
def : t2InstSubst<"add${s}${p} $Rd, $imm",
5107+
(t2SUBri rGPR:$Rd, rGPR:$Rd, t2_so_imm_neg:$imm,
49935108
pred:$p, cc_out:$s)>;
49945109
def : t2InstSubst<"add${s}${p} $Rd, $imm",
4995-
(t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm,
5110+
(t2SUBspImm GPRsp:$Rd, GPRsp:$Rd, t2_so_imm_neg:$imm,
49965111
pred:$p, cc_out:$s)>;
49975112
// Same for CMP <--> CMN via t2_so_imm_neg
49985113
def : t2InstSubst<"cmp${p} $Rd, $imm",

0 commit comments

Comments
 (0)