[X86] Remove patterns for ADC/SBB with immediate 8 and optimize during MC lowering...
authorShengchen Kan <shengchen.kan@intel.com>
Fri, 19 May 2023 02:30:44 +0000 (10:30 +0800)
committerShengchen Kan <shengchen.kan@intel.com>
Fri, 19 May 2023 02:33:52 +0000 (10:33 +0800)
This is follow-up of D150107.

llvm/lib/Target/X86/MCTargetDesc/X86EncodingOptimization.cpp
llvm/lib/Target/X86/MCTargetDesc/X86EncodingOptimization.h
llvm/lib/Target/X86/X86InstrArithmetic.td
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86MCInstLower.cpp

index 69f6584..5299583 100644 (file)
@@ -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;
+}
index 7d0c317..169283c 100644 (file)
@@ -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
index c4e4eb3..54cd283 100644 (file)
@@ -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]
 
index 1f66035..48be6ff 100644 (file)
@@ -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:
index 9194f44..c4a40bf 100644 (file)
@@ -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.