[llvm] r371240 - [X86] Teach FixupBWInsts to turn MOVSX16rr8/MOVZX16rr8/MOVSX16rm8/MOVZX16rm8 into their 32-bit dest equivalents when the upper part of the register is dead.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 6 12:14:50 PDT 2019


Author: ctopper
Date: Fri Sep  6 12:14:49 2019
New Revision: 371240

URL: http://llvm.org/viewvc/llvm-project?rev=371240&view=rev
Log:
[X86] Teach FixupBWInsts to turn MOVSX16rr8/MOVZX16rr8/MOVSX16rm8/MOVZX16rm8 into their 32-bit dest equivalents when the upper part of the register is dead.

Modified:
    llvm/trunk/lib/Target/X86/X86FixupBWInsts.cpp
    llvm/trunk/test/CodeGen/X86/fast-isel-divrem.ll

Modified: llvm/trunk/lib/Target/X86/X86FixupBWInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FixupBWInsts.cpp?rev=371240&r1=371239&r2=371240&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FixupBWInsts.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FixupBWInsts.cpp Fri Sep  6 12:14:49 2019
@@ -92,6 +92,12 @@ class FixupBWInstPass : public MachineFu
   /// nullptr.
   MachineInstr *tryReplaceCopy(MachineInstr *MI) const;
 
+  /// Change the MachineInstr \p MI into the equivalent extend to 32 bit
+  /// register if it is safe to do so.  Return the replacement instruction if
+  /// OK, otherwise return nullptr.
+  MachineInstr *tryReplaceExtend(unsigned New32BitOpcode,
+                                 MachineInstr *MI) const;
+
   // Change the MachineInstr \p MI into an eqivalent 32 bit instruction if
   // possible.  Return the replacement instruction if OK, return nullptr
   // otherwise.
@@ -232,12 +238,12 @@ bool FixupBWInstPass::getSuperRegDestIfD
   //   %ax = KILL %ax, implicit killed %eax
   //   RET 0, %ax
   unsigned Opc = OrigMI->getOpcode(); (void)Opc;
-  // These are the opcodes currently handled by the pass, if something
-  // else will be added we need to ensure that new opcode has the same
-  // properties.
-  assert((Opc == X86::MOV8rm || Opc == X86::MOV16rm || Opc == X86::MOV8rr ||
-          Opc == X86::MOV16rr) &&
-         "Unexpected opcode.");
+  // These are the opcodes currently known to work with the code below, if
+  // something // else will be added we need to ensure that new opcode has the
+  // same properties.
+  if (Opc != X86::MOV8rm && Opc != X86::MOV16rm && Opc != X86::MOV8rr &&
+      Opc != X86::MOV16rr)
+    return false;
 
   bool IsDefined = false;
   for (auto &MO: OrigMI->implicit_operands()) {
@@ -326,6 +332,33 @@ MachineInstr *FixupBWInstPass::tryReplac
   return MIB;
 }
 
+MachineInstr *FixupBWInstPass::tryReplaceExtend(unsigned New32BitOpcode,
+                                                MachineInstr *MI) const {
+  Register NewDestReg;
+  if (!getSuperRegDestIfDead(MI, NewDestReg))
+    return nullptr;
+
+  // Don't interfere with formation of CBW instructions which should be a
+  // shorter encoding than even the MOVSX32rr8. It's also immunte to partial
+  // merge issues on Intel CPUs.
+  if (MI->getOpcode() == X86::MOVSX16rr8 &&
+      MI->getOperand(0).getReg() == X86::AX &&
+      MI->getOperand(1).getReg() == X86::AL)
+    return nullptr;
+
+  // Safe to change the instruction.
+  MachineInstrBuilder MIB =
+      BuildMI(*MF, MI->getDebugLoc(), TII->get(New32BitOpcode), NewDestReg);
+
+  unsigned NumArgs = MI->getNumOperands();
+  for (unsigned i = 1; i < NumArgs; ++i)
+    MIB.add(MI->getOperand(i));
+
+  MIB.setMemRefs(MI->memoperands());
+
+  return MIB;
+}
+
 MachineInstr *FixupBWInstPass::tryReplaceInstr(MachineInstr *MI,
                                                MachineBasicBlock &MBB) const {
   // See if this is an instruction of the type we are currently looking for.
@@ -355,6 +388,15 @@ MachineInstr *FixupBWInstPass::tryReplac
     // of the register.
     return tryReplaceCopy(MI);
 
+  case X86::MOVSX16rr8:
+    return tryReplaceExtend(X86::MOVSX32rr8, MI);
+  case X86::MOVSX16rm8:
+    return tryReplaceExtend(X86::MOVSX32rm8, MI);
+  case X86::MOVZX16rr8:
+    return tryReplaceExtend(X86::MOVZX32rr8, MI);
+  case X86::MOVZX16rm8:
+    return tryReplaceExtend(X86::MOVZX32rm8, MI);
+
   default:
     // nothing to do here.
     break;

Modified: llvm/trunk/test/CodeGen/X86/fast-isel-divrem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-divrem.ll?rev=371240&r1=371239&r2=371240&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-divrem.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-divrem.ll Fri Sep  6 12:14:49 2019
@@ -8,7 +8,7 @@ entry:
 }
 
 ; CHECK-LABEL: test_sdiv8:
-; CHECK: movsbw
+; CHECK: movsbl
 ; CHECK: idivb
 
 define i8 @test_srem8(i8 %dividend, i8 %divisor) nounwind {
@@ -18,7 +18,7 @@ entry:
 }
 
 ; CHECK-LABEL: test_srem8:
-; CHECK: movsbw
+; CHECK: movsbl
 ; CHECK: idivb
 
 define i8 @test_udiv8(i8 %dividend, i8 %divisor) nounwind {
@@ -28,7 +28,7 @@ entry:
 }
 
 ; CHECK-LABEL: test_udiv8:
-; CHECK: movzbw
+; CHECK: movzbl
 ; CHECK: divb
 
 define i8 @test_urem8(i8 %dividend, i8 %divisor) nounwind {
@@ -38,7 +38,7 @@ entry:
 }
 
 ; CHECK-LABEL: test_urem8:
-; CHECK: movzbw
+; CHECK: movzbl
 ; CHECK: divb
 
 define i16 @test_sdiv16(i16 %dividend, i16 %divisor) nounwind {




More information about the llvm-commits mailing list