From 65bf80e2b7d3c839331be63cdd28a8d101936bca Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 15 Aug 2012 16:17:24 +0000 Subject: [PATCH] Add missing Rfalse operand to the predicated pseudo-instructions. When predicating this instruction: Rd = ADD Rn, Rm We need an extra operand to represent the value given to Rd when the predicate is false: Rd = ADDCC Rfalse, Rn, Rm, pred The Rd and Rfalse operands are different registers while in SSA form. Rfalse is tied to Rd to make sure they get the same register during register allocation. Previously, Rd and Rn were tied, but that is not required. Compare to MOVCC: Rd = MOVCC Rfalse, Rtrue, pred git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161955 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 34 ++++++++++++++++++------------ lib/Target/ARM/ARMInstrInfo.td | 20 +++++++++++------- lib/Target/ARM/ARMInstrThumb2.td | 15 +++++++------ 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index ee349a753fe..a3a6c3176be 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -2385,8 +2385,10 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::COR: Opc = ARM::t2ORRCCrs; break; case ARMISD::CXOR: Opc = ARM::t2EORCCrs; break; } - SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); + SDValue Ops[] = { + FalseVal, FalseVal, CPTmp0, CPTmp1, CC, CCR, Reg0, InFlag + }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 8); } ConstantSDNode *T = dyn_cast(TrueVal); @@ -2401,8 +2403,8 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::CXOR: Opc = ARM::t2EORCCri; break; } SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32); - SDValue Ops[] = { FalseVal, True, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 6); + SDValue Ops[] = { FalseVal, FalseVal, True, CC, CCR, Reg0, InFlag }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); } } @@ -2413,8 +2415,8 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::COR: Opc = ARM::t2ORRCCrr; break; case ARMISD::CXOR: Opc = ARM::t2EORCCrr; break; } - SDValue Ops[] = { FalseVal, TrueVal, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 6); + SDValue Ops[] = { FalseVal, FalseVal, TrueVal, CC, CCR, Reg0, InFlag }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); } SDValue CPTmp0; @@ -2428,8 +2430,10 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::COR: Opc = ARM::ORRCCrsi; break; case ARMISD::CXOR: Opc = ARM::EORCCrsi; break; } - SDValue Ops[] = { FalseVal, CPTmp0, CPTmp2, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); + SDValue Ops[] = { + FalseVal, FalseVal, CPTmp0, CPTmp2, CC, CCR, Reg0, InFlag + }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 8); } if (SelectRegShifterOperand(TrueVal, CPTmp0, CPTmp1, CPTmp2)) { @@ -2440,8 +2444,10 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::COR: Opc = ARM::ORRCCrsr; break; case ARMISD::CXOR: Opc = ARM::EORCCrsr; break; } - SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 8); + SDValue Ops[] = { + FalseVal, FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, Reg0, InFlag + }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 9); } ConstantSDNode *T = dyn_cast(TrueVal); @@ -2456,8 +2462,8 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::CXOR: Opc = ARM::EORCCri; break; } SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32); - SDValue Ops[] = { FalseVal, True, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 6); + SDValue Ops[] = { FalseVal, FalseVal, True, CC, CCR, Reg0, InFlag }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); } } @@ -2468,8 +2474,8 @@ SDNode *ARMDAGToDAGISel::SelectConditionalOp(SDNode *N) { case ARMISD::COR: Opc = ARM::ORRCCrr; break; case ARMISD::CXOR: Opc = ARM::EORCCrr; break; } - SDValue Ops[] = { FalseVal, TrueVal, CC, CCR, Reg0, InFlag }; - return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 6); + SDValue Ops[] = { FalseVal, FalseVal, TrueVal, CC, CCR, Reg0, InFlag }; + return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 7); } /// Target-specific DAG combining for ISD::XOR. diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6340a58f1a0..fbd7e7b8e5b 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -3989,25 +3989,29 @@ multiclass AsI1_bincc_irs { def ri : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s), + (ins GPR:$Rfalse, GPR:$Rn, so_imm:$imm, + pred:$p, cc_out:$s), 4, iii, [], (iri GPR:$Rd, GPR:$Rn, so_imm:$imm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; def rr : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), + (ins GPR:$Rfalse, GPR:$Rn, GPR:$Rm, + pred:$p, cc_out:$s), 4, iir, [], (irr GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; def rsi : ARMPseudoExpand<(outs GPR:$Rd), - (ins GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s), + (ins GPR:$Rfalse, GPR:$Rn, so_reg_imm:$shift, + pred:$p, cc_out:$s), 4, iis, [], (irsi GPR:$Rd, GPR:$Rn, so_reg_imm:$shift, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; def rsr : ARMPseudoExpand<(outs GPRnopc:$Rd), - (ins GPRnopc:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s), + (ins GPRnopc:$Rfalse, GPRnopc:$Rn, so_reg_reg:$shift, + pred:$p, cc_out:$s), 4, iis, [], (irsr GPR:$Rd, GPR:$Rn, so_reg_reg:$shift, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; } defm ANDCC : AsI1_bincc_irs { // shifted imm def ri : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s), + (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_imm:$imm, + pred:$p, cc_out:$s), 4, iii, [], (iri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; // register def rr : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s), + (ins rGPR:$Rfalse, rGPR:$Rn, rGPR:$Rm, + pred:$p, cc_out:$s), 4, iir, [], (irr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; // shifted register def rs : t2PseudoExpand<(outs rGPR:$Rd), - (ins rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s), + (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_reg:$ShiftedRm, + pred:$p, cc_out:$s), 4, iis, [], (irs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>, - RegConstraint<"$Rn = $Rd">; + RegConstraint<"$Rfalse = $Rd">; } // T2I_bincc_irs defm t2ANDCC : T2I_bincc_irs