forked from OSchip/llvm-project
Fix fall outs from my recent change on how carry bit is modeled during isel.
Now the 'S' instructions, e.g. ADDS, treat S bit as optional operand as well. Also fix isel hook to correctly set the optional operand. rdar://10073745 llvm-svn: 139157
This commit is contained in:
parent
c10e52a0c4
commit
0b758ed6ba
|
@ -5708,7 +5708,7 @@ void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI,
|
|||
// the optional operand to CPSR. Otherwise, remove the CPSR implicit def.
|
||||
const MCInstrDesc &MCID = MI->getDesc();
|
||||
if (Node->hasAnyUseOfValue(1)) {
|
||||
MachineOperand &MO = MI->getOperand(MCID.getNumOperands() - 2);
|
||||
MachineOperand &MO = MI->getOperand(MCID.getNumOperands() - 1);
|
||||
MO.setReg(ARM::CPSR);
|
||||
MO.setIsDef(true);
|
||||
} else {
|
||||
|
|
|
@ -1037,8 +1037,8 @@ multiclass AsI1_rbin_irs<bits<4> opcod, string opc,
|
|||
|
||||
}
|
||||
|
||||
/// AsI1_rbin_s_is - Same as AsI1_rbin_s_is except sets 's' bit.
|
||||
let isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
/// AsI1_rbin_s_is - Same as AsI1_rbin_s_is except it sets 's' bit by default.
|
||||
let hasPostISelHook = 1, isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
multiclass AsI1_rbin_s_is<bits<4> opcod, string opc,
|
||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
||||
PatFrag opnode, bit Commutable = 0> {
|
||||
|
@ -1101,25 +1101,25 @@ multiclass AsI1_rbin_s_is<bits<4> opcod, string opc,
|
|||
}
|
||||
}
|
||||
|
||||
/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
|
||||
/// instruction modifies the CPSR register.
|
||||
let isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
|
||||
/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default.
|
||||
let hasPostISelHook = 1, isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
multiclass AsI1_bin_s_irs<bits<4> opcod, string opc,
|
||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
||||
PatFrag opnode, bit Commutable = 0> {
|
||||
def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
|
||||
let isReMaterializable = 1 in {
|
||||
def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm,
|
||||
iii, opc, "\t$Rd, $Rn, $imm",
|
||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm))]> {
|
||||
bits<4> Rd;
|
||||
bits<4> Rn;
|
||||
bits<12> imm;
|
||||
let Inst{25} = 1;
|
||||
let Inst{20} = 1;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-0} = imm;
|
||||
}
|
||||
def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
|
||||
}
|
||||
def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm,
|
||||
iir, opc, "\t$Rd, $Rn, $Rm",
|
||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm))]> {
|
||||
bits<4> Rd;
|
||||
|
@ -1127,13 +1127,12 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
|
|||
bits<4> Rm;
|
||||
let isCommutable = Commutable;
|
||||
let Inst{25} = 0;
|
||||
let Inst{20} = 1;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-4} = 0b00000000;
|
||||
let Inst{3-0} = Rm;
|
||||
}
|
||||
def rsi : AI1<opcod, (outs GPR:$Rd),
|
||||
def rsi : AsI1<opcod, (outs GPR:$Rd),
|
||||
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm,
|
||||
iis, opc, "\t$Rd, $Rn, $shift",
|
||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
|
||||
|
@ -1141,7 +1140,6 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
|
|||
bits<4> Rn;
|
||||
bits<12> shift;
|
||||
let Inst{25} = 0;
|
||||
let Inst{20} = 1;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-5} = shift{11-5};
|
||||
|
@ -1149,7 +1147,7 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc,
|
|||
let Inst{3-0} = shift{3-0};
|
||||
}
|
||||
|
||||
def rsr : AI1<opcod, (outs GPR:$Rd),
|
||||
def rsr : AsI1<opcod, (outs GPR:$Rd),
|
||||
(ins GPR:$Rn, so_reg_reg:$shift), DPSoRegRegFrm,
|
||||
iis, opc, "\t$Rd, $Rn, $shift",
|
||||
[(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
|
||||
|
@ -3136,10 +3134,12 @@ defm SUB : AsI1_bin_irs<0b0010, "sub",
|
|||
BinOpFrag<(sub node:$LHS, node:$RHS)>, "SUB">;
|
||||
|
||||
// ADD and SUB with 's' bit set.
|
||||
defm ADDS : AI1_bin_s_irs<0b0100, "adds",
|
||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||
// CPSR and the implicit def of CPSR is not needed.
|
||||
defm ADDS : AsI1_bin_s_irs<0b0100, "add",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
||||
defm SUBS : AI1_bin_s_irs<0b0010, "subs",
|
||||
defm SUBS : AsI1_bin_s_irs<0b0010, "sub",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||
|
||||
|
@ -3153,6 +3153,9 @@ defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
|
|||
defm RSB : AsI1_rbin_irs <0b0011, "rsb",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(sub node:$LHS, node:$RHS)>, "RSB">;
|
||||
|
||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||
// CPSR and the implicit def of CPSR is not needed.
|
||||
defm RSBS : AsI1_rbin_s_is<0b0011, "rsb",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||
|
|
|
@ -588,44 +588,41 @@ multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> {
|
|||
|
||||
/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
|
||||
/// instruction modifies the CPSR register.
|
||||
let isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
let hasPostISelHook = 1, isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
multiclass T2I_bin_s_irs<bits<4> opcod, string opc,
|
||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
||||
PatFrag opnode, bit Commutable = 0> {
|
||||
// shifted imm
|
||||
def ri : T2TwoRegImm<
|
||||
def ri : T2sTwoRegImm<
|
||||
(outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii,
|
||||
!strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
|
||||
opc, ".w\t$Rd, $Rn, $imm",
|
||||
[(set rGPR:$Rd, CPSR, (opnode GPR:$Rn, t2_so_imm:$imm))]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 0;
|
||||
let Inst{24-21} = opcod;
|
||||
let Inst{20} = 1; // The S bit.
|
||||
let Inst{15} = 0;
|
||||
}
|
||||
// register
|
||||
def rr : T2ThreeReg<
|
||||
def rr : T2sThreeReg<
|
||||
(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir,
|
||||
!strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm",
|
||||
opc, ".w\t$Rd, $Rn, $Rm",
|
||||
[(set rGPR:$Rd, CPSR, (opnode GPR:$Rn, rGPR:$Rm))]> {
|
||||
let isCommutable = Commutable;
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
let Inst{24-21} = opcod;
|
||||
let Inst{20} = 1; // The S bit.
|
||||
let Inst{14-12} = 0b000; // imm3
|
||||
let Inst{7-6} = 0b00; // imm2
|
||||
let Inst{5-4} = 0b00; // type
|
||||
}
|
||||
// shifted register
|
||||
def rs : T2TwoRegShiftedReg<
|
||||
def rs : T2sTwoRegShiftedReg<
|
||||
(outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis,
|
||||
!strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm",
|
||||
opc, ".w\t$Rd, $Rn, $ShiftedRm",
|
||||
[(set rGPR:$Rd, CPSR, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
let Inst{24-21} = opcod;
|
||||
let Inst{20} = 1; // The S bit.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,28 +734,26 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
|
|||
|
||||
/// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register
|
||||
/// version is not needed since this is only for codegen.
|
||||
let isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
let hasPostISelHook = 1, isCodeGenOnly = 1, Defs = [CPSR] in {
|
||||
multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> {
|
||||
// shifted imm
|
||||
def ri : T2TwoRegImm<
|
||||
def ri : T2sTwoRegImm<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi,
|
||||
!strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm",
|
||||
opc, ".w\t$Rd, $Rn, $imm",
|
||||
[(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm, rGPR:$Rn))]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 0;
|
||||
let Inst{24-21} = opcod;
|
||||
let Inst{20} = 1; // The S bit.
|
||||
let Inst{15} = 0;
|
||||
}
|
||||
// shifted register
|
||||
def rs : T2TwoRegShiftedReg<
|
||||
def rs : T2sTwoRegShiftedReg<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm),
|
||||
IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm",
|
||||
IIC_iALUsi, opc, "\t$Rd, $Rn, $ShiftedRm",
|
||||
[(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> {
|
||||
let Inst{31-27} = 0b11101;
|
||||
let Inst{26-25} = 0b01;
|
||||
let Inst{24-21} = opcod;
|
||||
let Inst{20} = 1; // The S bit.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1699,6 +1694,8 @@ defm t2SUB : T2I_bin_ii12rs<0b101, "sub",
|
|||
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
|
||||
|
||||
// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
|
||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||
// CPSR and the implicit def of CPSR is not needed.
|
||||
defm t2ADDS : T2I_bin_s_irs <0b1000, "add",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsi,
|
||||
BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>;
|
||||
|
@ -1716,6 +1713,9 @@ defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc",
|
|||
// RSB
|
||||
defm t2RSB : T2I_rbin_irs <0b1110, "rsb",
|
||||
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
|
||||
|
||||
// FIXME: Eliminate them if we can write def : Pat patterns which defines
|
||||
// CPSR and the implicit def of CPSR is not needed.
|
||||
defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb",
|
||||
BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>;
|
||||
|
||||
|
|
|
@ -35,3 +35,13 @@ entry:
|
|||
%dw = add i64 %ch, %bw
|
||||
ret i64 %dw
|
||||
}
|
||||
|
||||
; rdar://10073745
|
||||
define i64 @f4(i64 %x) nounwind readnone {
|
||||
entry:
|
||||
; CHECK: f4:
|
||||
; CHECK: rsbs r
|
||||
; CHECK: rsc r
|
||||
%0 = sub nsw i64 0, %x
|
||||
ret i64 %0
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue