Commit 2ef8ae13 authored by Shengchen Kan's avatar Shengchen Kan
Browse files

[X86] Remove patterns for ADC/SBB with immediate 8 and optimize during MC lowering, NFCI

This is follow-up of D150107.
parent d9b84c2c
Loading
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -424,3 +424,27 @@ bool X86::optimizeToFixedRegisterForm(MCInst &MI) {
  MI.addOperand(Saved);
  return true;
}

bool X86::optimizeToShortImmediateForm(MCInst &MI) {
  unsigned NewOpc;
  switch (MI.getOpcode()) {
  default:
    return false;
    FROM_TO(ADC16mi, ADC16mi8)
    FROM_TO(ADC16ri, ADC16ri8)
    FROM_TO(ADC32mi, ADC32mi8)
    FROM_TO(ADC32ri, ADC32ri8)
    FROM_TO(ADC64mi32, ADC64mi8)
    FROM_TO(ADC64ri32, ADC64ri8)
    FROM_TO(SBB16mi, SBB16mi8)
    FROM_TO(SBB16ri, SBB16ri8)
    FROM_TO(SBB32mi, SBB32mi8)
    FROM_TO(SBB32ri, SBB32ri8)
    FROM_TO(SBB64mi32, SBB64mi8)
    FROM_TO(SBB64ri32, SBB64ri8)
  }
  if (!isInt<8>(MI.getOperand(MI.getNumOperands() - 1).getImm()))
    return false;
  MI.setOpcode(NewOpc);
  return true;
}
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ bool optimizeMOVSX(MCInst &MI);
bool optimizeINCDEC(MCInst &MI, bool In64BitMode);
bool optimizeMOV(MCInst &MI, bool In64BitMode);
bool optimizeToFixedRegisterForm(MCInst &MI);
bool optimizeToShortImmediateForm(MCInst &MI);
} // namespace X86
} // namespace llvm
#endif
+14 −25
Original line number Diff line number Diff line
@@ -251,14 +251,9 @@ class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
             [(set typeinfo.RegClass:$dst, EFLAGS,
               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;

// BinOpRI8_RFF - Binary instructions with inputs "reg, imm8", where the pattern
// has both a regclass and EFLAGS as a result, and has EFLAGS as input.
class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
                   SDPatternOperator opnode, Format f>
  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC,
             [(set typeinfo.RegClass:$dst, EFLAGS,
               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
                       EFLAGS))]>;
// BinOpRI8_RFF - Binary instructions with inputs "reg, imm8".
class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo, Format f>
  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC, []>;

// BinOpMR - Binary instructions with inputs "[mem], reg".
class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
@@ -362,15 +357,9 @@ class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
              (implicit EFLAGS)]>,
    Sched<[WriteALURMW]>;

// BinOpMI8_RMW_FF - Binary instructions with inputs "[mem], imm8", where the
// pattern sets EFLAGS and implicitly uses EFLAGS.
class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
                      SDPatternOperator opnode, Format f>
  : BinOpMI8<mnemonic, typeinfo, f,
             [(store (opnode (load addr:$dst),
                             typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
              (implicit EFLAGS)]>,
    Sched<[WriteADCRMW]>;
// BinOpMI8_RMW_FF - Binary instructions with inputs "[mem], imm8".
class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo, Format f>
  : BinOpMI8<mnemonic, typeinfo, f, []>, Sched<[WriteADCRMW]>;

// BinOpMI8_F - Binary instructions with inputs "[mem], imm8", where the pattern
// has EFLAGS as a result.
@@ -979,9 +968,9 @@ multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
        // NOTE: These are order specific, we want the ri8 forms to be listed
        // first so that they are slightly preferred to the ri forms.
        def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
        def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
        def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
        def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, RegMRM>;
        def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, RegMRM>;
        def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, RegMRM>;

        def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
        def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
@@ -996,10 +985,10 @@ multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,

    // NOTE: These are order specific, we want the mi8 forms to be listed
    // first so that they are slightly preferred to the mi forms.
    def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
    def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
    def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, MemMRM>;
    def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, MemMRM>;
    let Predicates = [In64BitMode] in
    def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
    def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, MemMRM>;

    def NAME#8mi    : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
    def NAME#16mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
@@ -1012,9 +1001,9 @@ multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
        hasSideEffects = 0 in {
      let Constraints = "$src1 = $dst" in
        def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
        def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, RegMRM>;
      let mayLoad = 1, mayStore = 1 in
        def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
        def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, MemMRM>;
    }
  } // Uses = [EFLAGS], Defs = [EFLAGS]

+2 −4
Original line number Diff line number Diff line
@@ -4245,13 +4245,11 @@ inline static bool isDefConvertible(const MachineInstr &MI, bool &NoSignFlag,
  case X86::ADD16rr:   case X86::ADD8rr:   case X86::ADD64rm:
  case X86::ADD32rm:   case X86::ADD16rm:  case X86::ADD8rm:
  case X86::INC64r:    case X86::INC32r:   case X86::INC16r: case X86::INC8r:
  case X86::ADC64ri32: case X86::ADC64ri8: case X86::ADC32ri:
  case X86::ADC32ri8:  case X86::ADC16ri:  case X86::ADC16ri8:
  case X86::ADC64ri32: case X86::ADC32ri:  case X86::ADC16ri:
  case X86::ADC8ri:    case X86::ADC64rr:  case X86::ADC32rr:
  case X86::ADC16rr:   case X86::ADC8rr:   case X86::ADC64rm:
  case X86::ADC32rm:   case X86::ADC16rm:  case X86::ADC8rm:
  case X86::SBB64ri32: case X86::SBB64ri8: case X86::SBB32ri:
  case X86::SBB32ri8:  case X86::SBB16ri:  case X86::SBB16ri8:
  case X86::SBB64ri32: case X86::SBB32ri:  case X86::SBB16ri:
  case X86::SBB8ri:    case X86::SBB64rr:  case X86::SBB32rr:
  case X86::SBB16rr:   case X86::SBB8rr:   case X86::SBB64rm:
  case X86::SBB32rm:   case X86::SBB16rm:  case X86::SBB8rm:
+2 −1
Original line number Diff line number Diff line
@@ -405,7 +405,8 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
      X86::optimizeVPCMPWithImmediateOneOrSix(OutMI) ||
      X86::optimizeMOVSX(OutMI) || X86::optimizeINCDEC(OutMI, In64BitMode) ||
      X86::optimizeMOV(OutMI, In64BitMode) ||
      X86::optimizeToFixedRegisterForm(OutMI))
      X86::optimizeToFixedRegisterForm(OutMI) ||
      X86::optimizeToShortImmediateForm(OutMI))
    return;

  // Handle a few special cases to eliminate operand modifiers.