Index: lib/CodeGen/LiveVariables.cpp =================================================================== --- lib/CodeGen/LiveVariables.cpp +++ lib/CodeGen/LiveVariables.cpp @@ -527,10 +527,6 @@ UseRegs.push_back(MOReg); } else { assert(MO.isDef()); - // FIXME: We should not remove any dead flags. However the MIPS RDDSP - // instruction needs it at the moment: http://llvm.org/PR27116. - if (Register::isPhysicalRegister(MOReg) && !MRI->isReserved(MOReg)) - MO.setIsDead(false); DefRegs.push_back(MOReg); } } Index: lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -127,7 +127,9 @@ /// ($pc) with explicit offset and destination register IsPCRelativeLoad = 1 << 6, /// HasFCCRegOperand - Instruction uses an $fcc register. - HasFCCRegOperand = 1 << 7 + HasFCCRegOperand = 1 << 7, + /// DefsDSPCtrl - Instruction defines parts of DSPControl register. + DefsDSPCtrl = 1 << 8 }; } Index: lib/Target/Mips/MicroMipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsDSPInstrInfo.td +++ lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -186,11 +186,14 @@ InstrItinClass Itinerary = itin; } class ABSQ_S_PH_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< - "absq_s.ph", int_mips_absq_s_ph, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>; + "absq_s.ph", int_mips_absq_s_ph, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>, + DefsDSPCtrl; class ABSQ_S_W_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< - "absq_s.w", int_mips_absq_s_w, NoItinerary, GPR32Opnd>, Defs<[DSPOutFlag20]>; + "absq_s.w", int_mips_absq_s_w, NoItinerary, GPR32Opnd>, Defs<[DSPOutFlag20]>, + DefsDSPCtrl; class ABSQ_S_QB_MMR2_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< - "absq_s.qb", int_mips_absq_s_qb, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>; + "absq_s.qb", int_mips_absq_s_qb, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>, + DefsDSPCtrl; class PRECEQ_W_PHL_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< "preceq.w.phl", int_mips_preceq_w_phl, NoItinerary, GPR32Opnd, DSPROpnd>; class PRECEQ_W_PHR_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< @@ -224,16 +227,16 @@ } class SHLL_PH_MM_DESC : SHLL_R2_MM_DESC_BASE< "shll.ph", null_frag, immZExt4, NoItinerary, DSPROpnd, uimm4>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLL_S_PH_MM_DESC : SHLL_R2_MM_DESC_BASE< "shll_s.ph", int_mips_shll_s_ph, immZExt4, NoItinerary, DSPROpnd, uimm4>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLL_QB_MM_DESC : SHLL_R2_MM_DESC_BASE< "shll.qb", null_frag, immZExt3, NoItinerary, DSPROpnd, uimm3>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLL_S_W_MM_DESC : SHLL_R2_MM_DESC_BASE< "shll_s.w", int_mips_shll_s_w, immZExt5, NoItinerary, GPR32Opnd, uimm5>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHRA_QB_MMR2_DESC : SHLL_R2_MM_DESC_BASE< "shra.qb", null_frag, immZExt3, NoItinerary, DSPROpnd, uimm3>; class SHRA_R_QB_MMR2_DESC : SHLL_R2_MM_DESC_BASE< @@ -258,14 +261,17 @@ InstrItinClass Itinerary = itin; } class SHLLV_PH_MM_DESC : SHLLV_R3_MM_DESC_BASE< - "shllv.ph", int_mips_shll_ph, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag22]>; + "shllv.ph", int_mips_shll_ph, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag22]>, + DefsDSPCtrl; class SHLLV_S_PH_MM_DESC : SHLLV_R3_MM_DESC_BASE< "shllv_s.ph", int_mips_shll_s_ph, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLLV_QB_MM_DESC : SHLLV_R3_MM_DESC_BASE< - "shllv.qb", int_mips_shll_qb, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag22]>; + "shllv.qb", int_mips_shll_qb, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag22]>, + DefsDSPCtrl; class SHLLV_S_W_MM_DESC : SHLLV_R3_MM_DESC_BASE< - "shllv_s.w", int_mips_shll_s_w, NoItinerary, GPR32Opnd>, Defs<[DSPOutFlag22]>; + "shllv_s.w", int_mips_shll_s_w, NoItinerary, GPR32Opnd>, Defs<[DSPOutFlag22]>, + DefsDSPCtrl; class SHRAV_PH_MM_DESC : SHLLV_R3_MM_DESC_BASE< "shrav.ph", int_mips_shra_ph, NoItinerary, DSPROpnd>; class SHRAV_R_PH_MM_DESC : SHLLV_R3_MM_DESC_BASE< @@ -298,40 +304,40 @@ class EXTP_MM_DESC : EXT_MM_1R_DESC_BASE<"extp", MipsEXTP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPEFI]>, DefsDSPCtrl; class EXTPDP_MM_DESC : EXT_MM_1R_DESC_BASE<"extpdp", MipsEXTPDP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>, DefsDSPCtrl; class EXTPDPV_MM_DESC : EXT_MM_2R_DESC_BASE<"extpdpv", MipsEXTPDP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>, DefsDSPCtrl; class EXTPV_MM_DESC : EXT_MM_2R_DESC_BASE<"extpv", MipsEXTP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPEFI]>, DefsDSPCtrl; class EXTR_W_MM_DESC : EXT_MM_1R_DESC_BASE<"extr.w", MipsEXTR_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTR_R_W_MM_DESC : EXT_MM_1R_DESC_BASE<"extr_r.w", MipsEXTR_R_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTR_RS_W_MM_DESC : EXT_MM_1R_DESC_BASE<"extr_rs.w", MipsEXTR_RS_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTR_S_H_MM_DESC : EXT_MM_1R_DESC_BASE<"extr_s.h", MipsEXTR_S_H, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_W_MM_DESC : EXT_MM_2R_DESC_BASE<"extrv.w", MipsEXTR_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_R_W_MM_DESC : EXT_MM_2R_DESC_BASE<"extrv_r.w", MipsEXTR_R_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_RS_W_MM_DESC : EXT_MM_2R_DESC_BASE<"extrv_rs.w", MipsEXTR_RS_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_S_H_MM_DESC : EXT_MM_2R_DESC_BASE<"extrv_s.h", MipsEXTR_S_H, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class MFHI_MM_DESC_BASE { @@ -362,6 +368,7 @@ string AsmString = !strconcat("rddsp", "\t$rt, $mask"); list Pattern = [(set GPR32Opnd:$rt, (int_mips_rddsp immZExt7:$mask))]; InstrItinClass Itinerary = NoItinerary; + bit defsDSPCtrl = 1; } class REPL_QB_MM_DESC { @@ -386,6 +393,7 @@ list Pattern = [(int_mips_wrdsp GPR32Opnd:$rt, immZExt7:$mask)]; InstrItinClass Itinerary = NoItinerary; bit isMoveReg = 1; + bit defsDSPCtrl = 1; } class BPOSGE32C_MMR3_DESC { Index: lib/Target/Mips/MipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MipsDSPInstrInfo.td +++ lib/Target/Mips/MipsDSPInstrInfo.td @@ -447,6 +447,7 @@ InstrItinClass Itinerary = itin; string BaseOpcode = instr_asm; bit isMoveReg = 1; + bit defsDSPCtrl = 1; } class WRDSP_DESC_BASE { @@ -549,51 +551,52 @@ // Addition/subtraction class ADDU_QB_DESC : ADDU_QB_DESC_BASE<"addu.qb", null_frag, NoItinerary, DSPROpnd, DSPROpnd>, IsCommutable, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDU_S_QB_DESC : ADDU_QB_DESC_BASE<"addu_s.qb", int_mips_addu_s_qb, NoItinerary, DSPROpnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag20]>; + IsCommutable, Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBU_QB_DESC : ADDU_QB_DESC_BASE<"subu.qb", null_frag, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBU_S_QB_DESC : ADDU_QB_DESC_BASE<"subu_s.qb", int_mips_subu_s_qb, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDQ_PH_DESC : ADDU_QB_DESC_BASE<"addq.ph", null_frag, NoItinerary, DSPROpnd, DSPROpnd>, IsCommutable, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDQ_S_PH_DESC : ADDU_QB_DESC_BASE<"addq_s.ph", int_mips_addq_s_ph, NoItinerary, DSPROpnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag20]>; + IsCommutable, Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBQ_PH_DESC : ADDU_QB_DESC_BASE<"subq.ph", null_frag, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBQ_S_PH_DESC : ADDU_QB_DESC_BASE<"subq_s.ph", int_mips_subq_s_ph, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDQ_S_W_DESC : ADDU_QB_DESC_BASE<"addq_s.w", int_mips_addq_s_w, NoItinerary, GPR32Opnd, GPR32Opnd>, - IsCommutable, Defs<[DSPOutFlag20]>; + IsCommutable, Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBQ_S_W_DESC : ADDU_QB_DESC_BASE<"subq_s.w", int_mips_subq_s_w, NoItinerary, GPR32Opnd, GPR32Opnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDSC_DESC : ADDU_QB_DESC_BASE<"addsc", null_frag, NoItinerary, GPR32Opnd, GPR32Opnd>, IsCommutable, - Defs<[DSPCarry]>; + Defs<[DSPCarry]>, DefsDSPCtrl; class ADDWC_DESC : ADDU_QB_DESC_BASE<"addwc", null_frag, NoItinerary, GPR32Opnd, GPR32Opnd>, - IsCommutable, Uses<[DSPCarry]>, Defs<[DSPOutFlag20]>; + IsCommutable, Uses<[DSPCarry]>, Defs<[DSPOutFlag20]>, + DefsDSPCtrl; class MODSUB_DESC : ADDU_QB_DESC_BASE<"modsub", int_mips_modsub, NoItinerary, GPR32Opnd, GPR32Opnd>; @@ -604,11 +607,11 @@ // Absolute value class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ABSQ_S_W_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.w", int_mips_absq_s_w, NoItinerary, GPR32Opnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; // Precision reduce/expand class PRECRQ_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.qb.ph", @@ -623,13 +626,13 @@ int_mips_precrq_rs_ph_w, NoItinerary, DSPROpnd, GPR32Opnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph", int_mips_precrqu_s_qb_ph, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class PRECEQ_W_PHL_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phl", int_mips_preceq_w_phl, @@ -674,11 +677,11 @@ // Shift class SHLL_QB_DESC : SHLL_QB_R2_DESC_BASE<"shll.qb", null_frag, immZExt3, NoItinerary, DSPROpnd, uimm3>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLLV_QB_DESC : SHLL_QB_R3_DESC_BASE<"shllv.qb", int_mips_shll_qb, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHRL_QB_DESC : SHLL_QB_R2_DESC_BASE<"shrl.qb", null_frag, immZExt3, NoItinerary, DSPROpnd, uimm3>; @@ -688,20 +691,20 @@ class SHLL_PH_DESC : SHLL_QB_R2_DESC_BASE<"shll.ph", null_frag, immZExt4, NoItinerary, DSPROpnd, uimm4>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLLV_PH_DESC : SHLL_QB_R3_DESC_BASE<"shllv.ph", int_mips_shll_ph, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLL_S_PH_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.ph", int_mips_shll_s_ph, immZExt4, NoItinerary, DSPROpnd, uimm4>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLLV_S_PH_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.ph", int_mips_shll_s_ph, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHRA_PH_DESC : SHLL_QB_R2_DESC_BASE<"shra.ph", null_frag, immZExt4, NoItinerary, DSPROpnd, uimm4>; @@ -719,11 +722,11 @@ class SHLL_S_W_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.w", int_mips_shll_s_w, immZExt5, NoItinerary, GPR32Opnd, uimm5>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHLLV_S_W_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.w", int_mips_shll_s_w, NoItinerary, GPR32Opnd>, - Defs<[DSPOutFlag22]>; + Defs<[DSPOutFlag22]>, DefsDSPCtrl; class SHRA_R_W_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.w", int_mips_shra_r_w, immZExt5, NoItinerary, GPR32Opnd, @@ -736,42 +739,42 @@ class MULEU_S_PH_QBL_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbl", int_mips_muleu_s_ph_qbl, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULEU_S_PH_QBR_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbr", int_mips_muleu_s_ph_qbr, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULEQ_S_W_PHL_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phl", int_mips_muleq_s_w_phl, NoItinerary, GPR32Opnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag21]>; + IsCommutable, Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULEQ_S_W_PHR_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phr", int_mips_muleq_s_w_phr, NoItinerary, GPR32Opnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag21]>; + IsCommutable, Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULQ_RS_PH_DESC : ADDU_QB_DESC_BASE<"mulq_rs.ph", int_mips_mulq_rs_ph, NoItinerary, DSPROpnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag21]>; + IsCommutable, Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULSAQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"mulsaq_s.w.ph", MipsMULSAQ_S_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MAQ_S_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phl", MipsMAQ_S_W_PHL>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MAQ_S_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phr", MipsMAQ_S_W_PHR>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MAQ_SA_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phl", MipsMAQ_SA_W_PHL>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MAQ_SA_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phr", MipsMAQ_SA_W_PHR>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; // Move from/to hi/lo. class MFHI_DESC : MFHI_DESC_BASE<"mfhi", ACC64DSPOpnd, MipsMFHI, NoItinerary>; @@ -789,16 +792,16 @@ class DPSU_H_QBR_DESC : DPA_W_PH_DESC_BASE<"dpsu.h.qbr", MipsDPSU_H_QBR>; class DPAQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaq_s.w.ph", MipsDPAQ_S_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPSQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsq_s.w.ph", MipsDPSQ_S_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPAQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpaq_sa.l.w", MipsDPAQ_SA_L_W>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPSQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpsq_sa.l.w", MipsDPSQ_SA_L_W>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MULT_DSP_DESC : MULT_DESC_BASE<"mult", MipsMult, NoItinerary>; class MULTU_DSP_DESC : MULT_DESC_BASE<"multu", MipsMultu, NoItinerary>; @@ -811,15 +814,17 @@ class CMPU_EQ_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.eq.qb", int_mips_cmpu_eq_qb, NoItinerary, DSPROpnd>, - IsCommutable, Defs<[DSPCCond]>; + IsCommutable, Defs<[DSPCCond]>, DefsDSPCtrl; class CMPU_LT_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.lt.qb", int_mips_cmpu_lt_qb, NoItinerary, - DSPROpnd>, Defs<[DSPCCond]>; + DSPROpnd>, Defs<[DSPCCond]>, + DefsDSPCtrl; class CMPU_LE_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.le.qb", int_mips_cmpu_le_qb, NoItinerary, - DSPROpnd>, Defs<[DSPCCond]>; + DSPROpnd>, Defs<[DSPCCond]>, + DefsDSPCtrl; class CMPGU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.eq.qb", int_mips_cmpgu_eq_qb, @@ -836,15 +841,15 @@ class CMP_EQ_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.eq.ph", int_mips_cmp_eq_ph, NoItinerary, DSPROpnd>, - IsCommutable, Defs<[DSPCCond]>; + IsCommutable, Defs<[DSPCCond]>, DefsDSPCtrl; class CMP_LT_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.lt.ph", int_mips_cmp_lt_ph, NoItinerary, DSPROpnd>, - Defs<[DSPCCond]>; + Defs<[DSPCCond]>, DefsDSPCtrl; class CMP_LE_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.le.ph", int_mips_cmp_le_ph, NoItinerary, DSPROpnd>, - Defs<[DSPCCond]>; + Defs<[DSPCCond]>, DefsDSPCtrl; // Misc class BITREV_DESC : ABSQ_S_PH_R2_DESC_BASE<"bitrev", int_mips_bitrev, @@ -867,11 +872,11 @@ class PICK_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.qb", int_mips_pick_qb, NoItinerary, DSPROpnd, DSPROpnd>, - Uses<[DSPCCond]>; + Uses<[DSPCCond]>, DefsDSPCtrl; class PICK_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.ph", int_mips_pick_ph, NoItinerary, DSPROpnd, DSPROpnd>, - Uses<[DSPCCond]>; + Uses<[DSPCCond]>, DefsDSPCtrl; class LWX_DESC : LX_DESC_BASE<"lwx", int_mips_lwx, NoItinerary>; @@ -883,53 +888,55 @@ // Extr class EXTP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extp", MipsEXTP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPEFI]>, DefsDSPCtrl; class EXTPV_DESC : EXTR_W_TY1_R2_DESC_BASE<"extpv", MipsEXTP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPEFI]>, DefsDSPCtrl; class EXTPDP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extpdp", MipsEXTPDP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>, DefsDSPCtrl; class EXTPDPV_DESC : EXTR_W_TY1_R2_DESC_BASE<"extpdpv", MipsEXTPDP, NoItinerary>, - Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>, DefsDSPCtrl; class EXTR_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr.w", MipsEXTR_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv.w", MipsEXTR_W, - NoItinerary>, Defs<[DSPOutFlag23]>; + NoItinerary>, Defs<[DSPOutFlag23]>, + DefsDSPCtrl; class EXTR_R_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_r.w", MipsEXTR_R_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_R_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_r.w", MipsEXTR_R_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTR_RS_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_rs.w", MipsEXTR_RS_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_RS_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_rs.w", MipsEXTR_RS_W, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTR_S_H_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_s.h", MipsEXTR_S_H, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class EXTRV_S_H_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_s.h", MipsEXTR_S_H, NoItinerary>, - Defs<[DSPOutFlag23]>; + Defs<[DSPOutFlag23]>, DefsDSPCtrl; class SHILO_DESC : SHILO_R1_DESC_BASE<"shilo", MipsSHILO>; class SHILOV_DESC : SHILO_R2_DESC_BASE<"shilov", MipsSHILO>; -class MTHLIP_DESC : MTHLIP_DESC_BASE<"mthlip", MipsMTHLIP>, Defs<[DSPPos]>; +class MTHLIP_DESC : MTHLIP_DESC_BASE<"mthlip", MipsMTHLIP>, Defs<[DSPPos]>, + DefsDSPCtrl; class RDDSP_DESC : RDDSP_DESC_BASE<"rddsp", int_mips_rddsp, NoItinerary>; @@ -943,19 +950,19 @@ // Addition/subtraction class ADDU_PH_DESC : ADDU_QB_DESC_BASE<"addu.ph", int_mips_addu_ph, NoItinerary, DSPROpnd, DSPROpnd>, IsCommutable, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDU_S_PH_DESC : ADDU_QB_DESC_BASE<"addu_s.ph", int_mips_addu_s_ph, NoItinerary, DSPROpnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag20]>; + IsCommutable, Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBU_PH_DESC : ADDU_QB_DESC_BASE<"subu.ph", int_mips_subu_ph, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class SUBU_S_PH_DESC : ADDU_QB_DESC_BASE<"subu_s.ph", int_mips_subu_s_ph, NoItinerary, DSPROpnd, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; class ADDUH_QB_DESC : ADDUH_QB_DESC_BASE<"adduh.qb", int_mips_adduh_qb, NoItinerary, DSPROpnd>, IsCommutable; @@ -997,43 +1004,43 @@ class CMPGDU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.eq.qb", int_mips_cmpgdu_eq_qb, NoItinerary, GPR32Opnd, DSPROpnd>, - IsCommutable, Defs<[DSPCCond]>; + IsCommutable, Defs<[DSPCCond]>, DefsDSPCtrl; class CMPGDU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.lt.qb", int_mips_cmpgdu_lt_qb, NoItinerary, GPR32Opnd, DSPROpnd>, - Defs<[DSPCCond]>; + Defs<[DSPCCond]>, DefsDSPCtrl; class CMPGDU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.le.qb", int_mips_cmpgdu_le_qb, NoItinerary, GPR32Opnd, DSPROpnd>, - Defs<[DSPCCond]>; + Defs<[DSPCCond]>, DefsDSPCtrl; // Absolute class ABSQ_S_QB_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.qb", int_mips_absq_s_qb, NoItinerary, DSPROpnd>, - Defs<[DSPOutFlag20]>; + Defs<[DSPOutFlag20]>, DefsDSPCtrl; // Multiplication class MUL_PH_DESC : ADDUH_QB_DESC_BASE<"mul.ph", null_frag, NoItinerary, DSPROpnd>, IsCommutable, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MUL_S_PH_DESC : ADDUH_QB_DESC_BASE<"mul_s.ph", int_mips_mul_s_ph, NoItinerary, DSPROpnd>, IsCommutable, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULQ_S_W_DESC : ADDUH_QB_DESC_BASE<"mulq_s.w", int_mips_mulq_s_w, NoItinerary, GPR32Opnd>, IsCommutable, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULQ_RS_W_DESC : ADDUH_QB_DESC_BASE<"mulq_rs.w", int_mips_mulq_rs_w, NoItinerary, GPR32Opnd>, IsCommutable, - Defs<[DSPOutFlag21]>; + Defs<[DSPOutFlag21]>, DefsDSPCtrl; class MULQ_S_PH_DESC : ADDU_QB_DESC_BASE<"mulq_s.ph", int_mips_mulq_s_ph, NoItinerary, DSPROpnd, DSPROpnd>, - IsCommutable, Defs<[DSPOutFlag21]>; + IsCommutable, Defs<[DSPOutFlag21]>, DefsDSPCtrl; // Dot product with accumulate/subtract class DPA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpa.w.ph", MipsDPA_W_PH>; @@ -1041,22 +1048,22 @@ class DPS_W_PH_DESC : DPA_W_PH_DESC_BASE<"dps.w.ph", MipsDPS_W_PH>; class DPAQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaqx_s.w.ph", MipsDPAQX_S_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPAQX_SA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaqx_sa.w.ph", MipsDPAQX_SA_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPAX_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpax.w.ph", MipsDPAX_W_PH>; class DPSX_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsx.w.ph", MipsDPSX_W_PH>; class DPSQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_s.w.ph", MipsDPSQX_S_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class DPSQX_SA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_sa.w.ph", MipsDPSQX_SA_W_PH>, - Defs<[DSPOutFlag16_19]>; + Defs<[DSPOutFlag16_19]>, DefsDSPCtrl; class MULSA_W_PH_DESC : DPA_W_PH_DESC_BASE<"mulsa.w.ph", MipsMULSA_W_PH>; Index: lib/Target/Mips/MipsInstrFormats.td =================================================================== --- lib/Target/Mips/MipsInstrFormats.td +++ lib/Target/Mips/MipsInstrFormats.td @@ -102,6 +102,7 @@ // register bit hasFCCRegOperand = 0; // Instruction uses $fcc register and is // present in MIPS-I to MIPS-III. + bit defsDSPCtrl = 0; // Instruction defines parts of DSPControl register. // TSFlags layout should be kept in sync with MCTargetDesc/MipsBaseInfo.h. let TSFlags{3-0} = FormBits; @@ -109,6 +110,7 @@ let TSFlags{5} = hasForbiddenSlot; let TSFlags{6} = IsPCRelativeLoad; let TSFlags{7} = hasFCCRegOperand; + let TSFlags{8} = defsDSPCtrl; let DecoderNamespace = "Mips"; Index: lib/Target/Mips/MipsInstrInfo.h =================================================================== --- lib/Target/Mips/MipsInstrInfo.h +++ lib/Target/Mips/MipsInstrInfo.h @@ -95,6 +95,10 @@ /// Predicate to determine if an instruction has a forbidden slot. bool HasForbiddenSlot(const MachineInstr &MI) const; + /// Predicate to determine if an instruction defines parts of DSPControl + /// register. + bool DefsDSPControl(const MachineInstr &MI) const; + /// Insert nop instruction when hazard condition is found void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override; Index: lib/Target/Mips/MipsInstrInfo.cpp =================================================================== --- lib/Target/Mips/MipsInstrInfo.cpp +++ lib/Target/Mips/MipsInstrInfo.cpp @@ -572,6 +572,12 @@ return (MI.getDesc().TSFlags & MipsII::HasForbiddenSlot) != 0; } +/// Predicate for distingushing instructions that define parts of DSPControl +/// register. +bool MipsInstrInfo::DefsDSPControl(const MachineInstr &MI) const { + return (MI.getDesc().TSFlags & MipsII::DefsDSPCtrl) != 0; +} + /// Return the number of bytes of code the specified instruction may be. unsigned MipsInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { switch (MI.getOpcode()) { Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -544,6 +544,10 @@ bit hasSideEffects = 0; } +class DefsDSPCtrl { + bit defsDSPCtrl = 1; +} + //===----------------------------------------------------------------------===// // Instruction format superclass //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsRegisterInfo.h =================================================================== --- lib/Target/Mips/MipsRegisterInfo.h +++ lib/Target/Mips/MipsRegisterInfo.h @@ -74,6 +74,12 @@ /// Return GPR register class. virtual const TargetRegisterClass *intRegClass(unsigned Size) const = 0; + /// Checks if a register is part of DSPControl register. + static bool isDSPControlReg(unsigned Reg); + + /// Return DSPOutFlag if a register is a SubReg of it. + static unsigned getDSPOutFlagIfSubreg(unsigned Reg); + private: virtual void eliminateFI(MachineBasicBlock::iterator II, unsigned OpNo, int FrameIndex, uint64_t StackSize, Index: lib/Target/Mips/MipsRegisterInfo.cpp =================================================================== --- lib/Target/Mips/MipsRegisterInfo.cpp +++ lib/Target/Mips/MipsRegisterInfo.cpp @@ -324,3 +324,17 @@ // sized objects. return MF.getRegInfo().canReserveReg(BP); } + +bool MipsRegisterInfo::isDSPControlReg(unsigned Reg) { + return Reg == Mips::DSPPos || Reg == Mips::DSPSCount || + Reg == Mips::DSPCarry || Reg == Mips::DSPOutFlag || + Reg == Mips::DSPCCond || Reg == Mips::DSPEFI; +} + +unsigned MipsRegisterInfo::getDSPOutFlagIfSubreg(unsigned Reg) { + if (Reg == Mips::DSPOutFlag20 || Reg == Mips::DSPOutFlag21 || + Reg == Mips::DSPOutFlag22 || Reg == Mips::DSPOutFlag23 || + Reg == Mips::DSPOutFlag16_19) + return Mips::DSPOutFlag; + return Reg; +} Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -472,6 +472,11 @@ } def DSPCC : RegisterClass<"Mips", [v4i8, v2i16], 32, (add DSPCCond)>; +def DSPC : RegisterClass<"Mips", [v4i8, v2i16, i32], 32, (add DSPCarry)>; +def DSPE : RegisterClass<"Mips", [v4i8, v2i16, i32], 32, (add DSPEFI)>; +def DSPOF : RegisterClass<"Mips", [v4i8, v2i16, i32], 32, (add DSPOutFlag)>; +def DSPPP : RegisterClass<"Mips", [v4i8, v2i16, i32], 32, (add DSPPos)>; +def DSPSC : RegisterClass<"Mips", [v4i8, v2i16, i32], 32, (add DSPSCount)>; // Coprocessor 0 registers. def COP0 : RegisterClass<"Mips", [i32], 32, (sequence "COP0%u", 0, 31)>, Index: lib/Target/Mips/MipsSEISelDAGToDAG.h =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.h +++ lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -29,8 +29,32 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; - void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, - MachineFunction &MF); + void addRegAndLiveIn(unsigned Reg, unsigned Flag, unsigned AddLiveIn, + MachineInstrBuilder &MIB, MachineFunction &MF, + MachineBasicBlock &MBB); + + void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MachineFunction &MF, + MachineBasicBlock &MBB); + + /// Instructions using DSPControl register are added as implicit operands and + /// their dead flags need to be handled manually. Keeps track of operands + /// marked as dead in DeadImplRegs that may need to be removed if a later use + /// is found. + void handleInstrUsingDSPControlReg( + DenseMap &DeadImplRegs, MachineInstr &MI); + + /// Called by 'handleInstrUsingDSPControlReg' when it finds a use of a + /// DSPControl register. If there was an operand which previously used such + /// register it will be in DeadImplRegs. It and it's dead flag will be removed + /// from DeadImplRegs. + void removeOperandFromDeadImplRegs( + DenseMap &DeadImplRegs, unsigned Reg); + + /// Called by 'handleInstrUsingDSPControlReg' when it finds a use of a + /// DSPControl register. If it is also a def and marked dead by + /// 'MachineInstr::setPhysRegsDeadExcept' it will be saved in DeadImplRegs. + void checkOperandForDeadImplRegs( + DenseMap &DeadImplRegs, MachineOperand &MO); unsigned getMSACtrlReg(const SDValue RegIdx) const; Index: lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -48,30 +48,47 @@ SelectionDAGISel::getAnalysisUsage(AU); } +void MipsSEDAGToDAGISel::addRegAndLiveIn(unsigned Reg, unsigned Flag, + unsigned AddLiveIn, + MachineInstrBuilder &MIB, + MachineFunction &MF, + MachineBasicBlock &MBB) { + MIB.addReg(Reg, Flag); + if (AddLiveIn) { + MachineRegisterInfo &MRI = MF.getRegInfo(); + const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); + if (!MRI.isLiveIn(Reg)) + MF.addLiveIn(Reg, TRI->getMinimalPhysRegClass(Reg)); + if (!MBB.isLiveIn(Reg)) + MBB.addLiveIn(Reg); + } +} + void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, - MachineFunction &MF) { + MachineFunction &MF, + MachineBasicBlock &MBB) { MachineInstrBuilder MIB(MF, &MI); unsigned Mask = MI.getOperand(1).getImm(); unsigned Flag = IsDef ? RegState::ImplicitDefine : RegState::Implicit | RegState::Undef; if (Mask & 1) - MIB.addReg(Mips::DSPPos, Flag); + addRegAndLiveIn(Mips::DSPPos, Flag, !IsDef, MIB, MF, MBB); if (Mask & 2) - MIB.addReg(Mips::DSPSCount, Flag); + addRegAndLiveIn(Mips::DSPSCount, Flag, !IsDef, MIB, MF, MBB); if (Mask & 4) - MIB.addReg(Mips::DSPCarry, Flag); + addRegAndLiveIn(Mips::DSPCarry, Flag, !IsDef, MIB, MF, MBB); if (Mask & 8) - MIB.addReg(Mips::DSPOutFlag, Flag); + addRegAndLiveIn(Mips::DSPOutFlag, Flag, !IsDef, MIB, MF, MBB); if (Mask & 16) - MIB.addReg(Mips::DSPCCond, Flag); + addRegAndLiveIn(Mips::DSPCCond, Flag, !IsDef, MIB, MF, MBB); if (Mask & 32) - MIB.addReg(Mips::DSPEFI, Flag); + addRegAndLiveIn(Mips::DSPEFI, Flag, !IsDef, MIB, MF, MBB); } unsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const { @@ -124,19 +141,69 @@ return true; } +void MipsSEDAGToDAGISel::handleInstrUsingDSPControlReg( + DenseMap &DeadImplRegs, MachineInstr &MI) { + for (MachineOperand &MO : MI.implicit_operands()) { + if (MO.isRegMask() || !MO.isReg()) + continue; + unsigned MOReg = MO.getReg(); + if (!Register::isPhysicalRegister(MOReg)) + continue; + MOReg = MipsRegisterInfo::getDSPOutFlagIfSubreg(MOReg); + if (MipsRegisterInfo::isDSPControlReg(MOReg)) { + // Check if there was a previous def of this register and was marked dead. + removeOperandFromDeadImplRegs(DeadImplRegs, MOReg); + // If this one is marked dead then keep track of it. + checkOperandForDeadImplRegs(DeadImplRegs, MO); + } + } +} + +void MipsSEDAGToDAGISel::removeOperandFromDeadImplRegs( + DenseMap &DeadImplRegs, unsigned Reg) { + auto Res = DeadImplRegs.find(Reg); + if (Res != DeadImplRegs.end()) { + if (Res->second->isDead()) + // We have found a use of a register which was previously marked as dead. + // It was wrongly marked as dead because it could not see this operand + // earlier, so now we need to correct it. Scheduling is not dependant on + // it. + Res->second->setIsDead(false); + DeadImplRegs.erase(Res); + } +} + +void MipsSEDAGToDAGISel::checkOperandForDeadImplRegs( + DenseMap &DeadImplRegs, MachineOperand &MO) { + if (!MO.isDef()) + return; + unsigned Reg = MO.getReg(); + Reg = MipsRegisterInfo::getDSPOutFlagIfSubreg(Reg); + if (MO.isDead()) + // Found an implicit operand which uses a physical register marked dead. In + // some cases dead flag may be incorrect because current instruction is not + // glued to all other instructions that may be using that same register + // (such as RDDSP and WRDSP). We keep track of these operands in + // DeadImplRegs in case they need to be corrected later. + DeadImplRegs[Reg] = &MO; +} + void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { MF.getInfo()->initGlobalBaseReg(); MachineRegisterInfo *MRI = &MF.getRegInfo(); for (auto &MBB: MF) { + DenseMap DeadImplRegs; for (auto &MI: MBB) { switch (MI.getOpcode()) { case Mips::RDDSP: - addDSPCtrlRegOperands(false, MI, MF); + case Mips::RDDSP_MM: + addDSPCtrlRegOperands(false, MI, MF, MBB); break; case Mips::WRDSP: - addDSPCtrlRegOperands(true, MI, MF); + case Mips::WRDSP_MM: + addDSPCtrlRegOperands(true, MI, MF, MBB); break; case Mips::BuildPairF64_64: case Mips::ExtractElementF64_64: @@ -153,6 +220,8 @@ default: replaceUsesWithZeroReg(MRI, MI); } + if (Subtarget->getInstrInfo()->DefsDSPControl(MI)) + handleInstrUsingDSPControlReg(DeadImplRegs, MI); } } } Index: test/CodeGen/Mips/dsp-implicit-dead.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/dsp-implicit-dead.ll @@ -0,0 +1,127 @@ +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+dspr2 -verify-machineinstrs \ +; RUN: -stop-before=finalize-isel -o - < %s | FileCheck %s + +; Checks that implicit operands that use DSPControl register such as RDDSP and +; WRDSP are not incorrectly marked dead in previous or later instructions. + +declare i32 @llvm.mips.rddsp(i32) nounwind readonly +declare void @llvm.mips.cmpu.le.qb(<4 x i8>, <4 x i8>) nounwind + +define i32 @test__builtin_mips_cmpu_le_qb_before_rddsp(i32 %i0, i32 %a0.coerce, i32 %a1.coerce) nounwind { + ; CHECK-LABEL: name: test__builtin_mips_cmpu_le_qb_before_rddsp + ; CHECK: liveins: + ; CHECK: - { reg: '$a1', virtual-reg: '[[LIVEIN:%[0-9]+]]' } + ; CHECK: - { reg: '$a2', virtual-reg: '[[LIVEIN1:%[0-9]+]]' } + ; CHECK: - { reg: '$dspccond', virtual-reg: '[[LIVEIN2:%[0-9]+]]' } + ; CHECK: bb.0.entry: + ; CHECK: liveins: $a1, $a2, $dspccond + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $a2 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1 + ; CHECK: [[COPY2:%[0-9]+]]:dspr = COPY [[COPY]] + ; CHECK: [[COPY3:%[0-9]+]]:dspr = COPY [[COPY1]] + ; CHECK: CMPU_LE_QB killed [[COPY3]], killed [[COPY2]], implicit-def $dspccond + ; CHECK: [[RDDSP:%[0-9]+]]:gpr32 = RDDSP 16, implicit undef $dspccond + ; CHECK: $v0 = COPY [[RDDSP]] + ; CHECK: RetRA implicit $v0 +entry: + %0 = bitcast i32 %a0.coerce to <4 x i8> + %1 = bitcast i32 %a1.coerce to <4 x i8> + tail call void @llvm.mips.cmpu.le.qb(<4 x i8> %0, <4 x i8> %1) + %2 = tail call i32 @llvm.mips.rddsp(i32 16) + ret i32 %2 +} + +declare void @llvm.mips.wrdsp(i32, i32) nounwind +declare <4 x i8> @llvm.mips.pick.qb(<4 x i8>, <4 x i8>) nounwind readonly + +define i32 @test__builtin_mips_pick_qb_after_wrdsp(i32 %i0, i32 %a0.coerce, i32 %a1.coerce) nounwind readonly { + ; CHECK-LABEL: name: test__builtin_mips_pick_qb_after_wrdsp + ; CHECK: liveins: + ; CHECK: - { reg: '$a0', virtual-reg: '[[LIVEIN:%[0-9]+]]' } + ; CHECK: - { reg: '$a1', virtual-reg: '[[LIVEIN1:%[0-9]+]]' } + ; CHECK: - { reg: '$a2', virtual-reg: '[[LIVEIN2:%[0-9]+]]' } + ; CHECK: bb.0.entry: + ; CHECK: liveins: $a0, $a1, $a2 + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $a2 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1 + ; CHECK: [[COPY2:%[0-9]+]]:gpr32 = COPY $a0 + ; CHECK: WRDSP [[COPY2]], 16, implicit-def $dspccond + ; CHECK: [[COPY3:%[0-9]+]]:dspr = COPY [[COPY]] + ; CHECK: [[COPY4:%[0-9]+]]:dspr = COPY [[COPY1]] + ; CHECK: [[PICK_QB:%[0-9]+]]:dspr = PICK_QB killed [[COPY4]], killed [[COPY3]], implicit $dspccond + ; CHECK: [[COPY5:%[0-9]+]]:gpr32 = COPY [[PICK_QB]] + ; CHECK: $v0 = COPY [[COPY5]] + ; CHECK: RetRA implicit $v0 +entry: + %0 = bitcast i32 %a0.coerce to <4 x i8> + %1 = bitcast i32 %a1.coerce to <4 x i8> + tail call void @llvm.mips.wrdsp(i32 %i0, i32 16) + %2 = tail call <4 x i8> @llvm.mips.pick.qb(<4 x i8> %0, <4 x i8> %1) + %3 = bitcast <4 x i8> %2 to i32 + ret i32 %3 +} + +declare i32 @llvm.mips.extpdp(i64, i32) nounwind + +define i32 @test__builtin_mips_extpdp_before_rddsp(i32 %i0, i32, i64 %a0) nounwind { + ; CHECK-LABEL: name: test__builtin_mips_extpdp_before_rddsp + ; CHECK: liveins: + ; CHECK: - { reg: '$a2', virtual-reg: '[[LIVEIN:%[0-9]+]]' } + ; CHECK: - { reg: '$a3', virtual-reg: '[[LIVEIN1:%[0-9]+]]' } + ; CHECK: - { reg: '$dsppos', virtual-reg: '[[LIVEIN2:%[0-9]+]]' } + ; CHECK: - { reg: '$dspefi', virtual-reg: '[[LIVEIN3:%[0-9]+]]' } + ; CHECK: bb.0.entry: + ; CHECK: liveins: $a2, $a3, $dsppos, $dspefi + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $a3 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $a2 + ; CHECK: [[PseudoMTLOHI_DSP:%[0-9]+]]:acc64dsp = PseudoMTLOHI_DSP [[COPY1]], [[COPY]] + ; CHECK: [[EXTPDP:%[0-9]+]]:gpr32 = EXTPDP killed [[PseudoMTLOHI_DSP]], 15, implicit-def $dsppos, implicit-def $dspefi, implicit $dsppos + ; CHECK: [[RDDSP:%[0-9]+]]:gpr32 = RDDSP 33, implicit undef $dsppos, implicit undef $dspefi + ; CHECK: [[ADDu:%[0-9]+]]:gpr32 = ADDu killed [[EXTPDP]], killed [[RDDSP]] + ; CHECK: $v0 = COPY [[ADDu]] + ; CHECK: RetRA implicit $v0 +entry: + %1 = tail call i32 @llvm.mips.extpdp(i64 %a0, i32 15) + %2 = tail call i32 @llvm.mips.rddsp(i32 33) + %3 = add i32 %1, %2 + ret i32 %3 +} + +declare i32 @llvm.mips.addwc(i32, i32) nounwind + +define i32 @test__builtin_mips_addwc_before_rddsp(i32 %i0, i32 %a0, i32 %a1) nounwind { + ; CHECK-LABEL: name: test__builtin_mips_addwc_before_rddsp + ; CHECK: liveins: + ; CHECK: - { reg: '$a1', virtual-reg: '[[LIVEIN:%[0-9]+]]' } + ; CHECK: - { reg: '$a2', virtual-reg: '[[LIVEIN1:%[0-9]+]]' } + ; CHECK: - { reg: '$dspcarry', virtual-reg: '[[LIVEIN2:%[0-9]+]]' } + ; CHECK: - { reg: '$dspoutflag', virtual-reg: '[[LIVEIN3:%[0-9]+]]' } + ; CHECK: bb.0.entry: + ; CHECK: liveins: $a1, $a2, $dspcarry, $dspoutflag + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $a2 + ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1 + ; CHECK: [[ADDWC:%[0-9]+]]:gpr32 = ADDWC [[COPY1]], [[COPY]], implicit-def $dspoutflag20, implicit $dspcarry + ; CHECK: [[RDDSP:%[0-9]+]]:gpr32 = RDDSP 12, implicit undef $dspcarry, implicit undef $dspoutflag + ; CHECK: $v0 = COPY [[RDDSP]] + ; CHECK: RetRA implicit $v0 +entry: + %0 = tail call i32 @llvm.mips.addwc(i32 %a0, i32 %a1) + %1 = tail call i32 @llvm.mips.rddsp(i32 12) + ret i32 %1 +} + +define i32 @test__builtin_mips_only_rddsp(i32 %i0, i32 %a0.coerce, i32 %a1.coerce) nounwind { + ; CHECK-LABEL: name: test__builtin_mips_only_rddsp + ; CHECK: liveins: + ; CHECK: - { reg: '$dspccond', virtual-reg: '[[LIVEIN:%[0-9]+]]' } + ; CHECK: bb.0.entry: + ; CHECK: liveins: $dspccond + ; CHECK: [[RDDSP:%[0-9]+]]:gpr32 = RDDSP 16, implicit undef $dspccond + ; CHECK: $v0 = COPY [[RDDSP]] + ; CHECK: RetRA implicit $v0 +entry: + %0 = bitcast i32 %a0.coerce to <4 x i8> + %1 = bitcast i32 %a1.coerce to <4 x i8> + %2 = tail call i32 @llvm.mips.rddsp(i32 16) + ret i32 %2 +}