From 4a51708448e8958d8d1a375c055f1b98c8e20926 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 6 Sep 2011 18:52:20 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139157 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 2 +- lib/Target/ARM/ARMInstrInfo.td | 33 ++++++++++++++++------------- lib/Target/ARM/ARMInstrThumb2.td | 34 +++++++++++++++--------------- test/CodeGen/ARM/carry.ll | 10 +++++++++ 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 0756be39bc1..64ceac4b6e2 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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 { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 7ec6ce28b5a..9806d058a31 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1037,8 +1037,8 @@ multiclass AsI1_rbin_irs 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 opcod, string opc, InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, PatFrag opnode, bit Commutable = 0> { @@ -1101,25 +1101,25 @@ multiclass AsI1_rbin_s_is 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 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 opcod, string opc, InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, PatFrag opnode, bit Commutable = 0> { - def ri : AI1 { 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 { bits<4> Rd; @@ -1127,13 +1127,12 @@ multiclass AI1_bin_s_irs 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 { @@ -1141,7 +1140,6 @@ multiclass AI1_bin_s_irs 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 opcod, string opc, let Inst{3-0} = shift{3-0}; } - def rsr : AI1 { @@ -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)>>; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index c6a3e5010fa..1bdc0decefb 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -588,44 +588,41 @@ multiclass T2I_rbin_irs 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 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 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 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)>>; diff --git a/test/CodeGen/ARM/carry.ll b/test/CodeGen/ARM/carry.ll index 06b459e48b4..f84774d9b61 100644 --- a/test/CodeGen/ARM/carry.ll +++ b/test/CodeGen/ARM/carry.ll @@ -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 +} -- 2.34.1