Index: lib/Target/X86/X86InstrCMovSetCC.td =================================================================== --- lib/Target/X86/X86InstrCMovSetCC.td +++ lib/Target/X86/X86InstrCMovSetCC.td @@ -91,6 +91,13 @@ [(store (X86setcc OpNode, EFLAGS), addr:$dst)], IIC_SET_M>, TB, Sched<[WriteALU, WriteStore]>; } // Uses = [EFLAGS] + + let Uses = [EFLAGS], isPseudo = 1, Constraints = "$src = $dst" in { + def r32_32 : I<0, Pseudo, (outs GR32_ABCD:$dst), (ins GR32_ABCD:$src), "", + [], IIC_ALU_NONMEM>, Sched<[WriteZero]>; + def r32_64 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src), "", + [], IIC_ALU_NONMEM>, Sched<[WriteZero]>; + } // Uses = [EFLAGS], Constraints = "$src = $dst" } defm SETO : SETCC<0x90, "seto", X86_COND_O>; // is overflow bit set Index: lib/Target/X86/X86InstrCompiler.td =================================================================== --- lib/Target/X86/X86InstrCompiler.td +++ lib/Target/X86/X86InstrCompiler.td @@ -1138,6 +1138,36 @@ defm : CMOVmr; defm : CMOVmr; +multiclass SETCC32 { + def : Pat<(i32 (zext (i8 (X86setcc Cond, EFLAGS)))), + (SetCCr32_32 (MOV32r0))>, + Requires<[Not64BitMode]>; + def : Pat<(i32 (zext (i8 (X86setcc Cond, EFLAGS)))), + (SetCCr32_64 (MOV32r0))>, + Requires<[In64BitMode]>; + def : Pat<(i64 (zext (i8 (X86setcc Cond, EFLAGS)))), + (SUBREG_TO_REG (i64 0), (SetCCr32_64 (MOV32r0)), sub_32bit)>, + Requires<[In64BitMode]>; +} + +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; +defm : SETCC32; + // zextload bool -> zextload byte def : Pat<(zextloadi8i1 addr:$src), (AND8ri (MOV8rm addr:$src), (i8 1))>; def : Pat<(zextloadi16i1 addr:$src), (AND16ri8 (MOVZX16rm8 addr:$src), (i16 1))>; Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -5355,6 +5355,17 @@ MIB.addReg(Reg, RegState::Kill).addImm(1).addReg(0).addImm(0).addReg(0); } +static bool ExpandSetCCPseudo(MachineInstrBuilder &MIB, + const MCInstrDesc &Desc) { + MachineOperand &DestOp = MIB->getOperand(0); + unsigned Reg = getX86SubSuperRegister(DestOp.getReg(), 8); + + MIB->setDesc(Desc); + DestOp.setReg(Reg); + + return true; +} + bool X86InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { bool HasAVX = Subtarget.hasAVX(); MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); @@ -5393,6 +5404,39 @@ MI->setDesc(get(X86::MOV32ri)); return true; + case X86::SETOr32_64: + case X86::SETOr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETOr)); + case X86::SETNOr32_64: + case X86::SETNOr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETNOr)); + case X86::SETBr32_64: + case X86::SETBr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETBr)); + case X86::SETAEr32_64: + case X86::SETAEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETAEr)); + case X86::SETEr32_64: + case X86::SETEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETEr)); + case X86::SETNEr32_64: + case X86::SETNEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETNEr)); + case X86::SETBEr32_64: + case X86::SETBEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETBEr)); + case X86::SETAr32_64: + case X86::SETAr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETAr)); + case X86::SETSr32_64: + case X86::SETSr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETSr)); + case X86::SETNSr32_64: + case X86::SETNSr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETNSr)); + case X86::SETPr32_64: + case X86::SETPr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETPr)); + case X86::SETNPr32_64: + case X86::SETNPr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETNPr)); + case X86::SETLr32_64: + case X86::SETLr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETLr)); + case X86::SETGEr32_64: + case X86::SETGEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETGEr)); + case X86::SETLEr32_64: + case X86::SETLEr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETLEr)); + case X86::SETGr32_64: + case X86::SETGr32_32: return ExpandSetCCPseudo(MIB, get(X86::SETGr)); + // KNL does not recognize dependency-breaking idioms for mask registers, // so kxnor %k1, %k1, %k2 has a RAW dependence on %k1. // Using %k0 as the undef input register is a performance heuristic based Index: utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- utils/TableGen/CodeGenDAGPatterns.cpp +++ utils/TableGen/CodeGenDAGPatterns.cpp @@ -2138,7 +2138,9 @@ error("Pattern has unexpected init kind!"); } DefInit *OpDef = dyn_cast(Dag->getOperator()); - if (!OpDef) error("Pattern has unexpected operator type!"); + if (!OpDef) { + error("Pattern has unexpected operator type!"); + } Record *Operator = OpDef->getDef(); if (Operator->isSubClassOf("ValueType")) {