[llvm] r205889 - [ARM64] Fix canonicalisation of MOVs. MOV is too complex to be modelled by a dumb alias.

Bradley Smith bradley.smith at arm.com
Wed Apr 9 07:44:18 PDT 2014


Author: brasmi01
Date: Wed Apr  9 09:44:18 2014
New Revision: 205889

URL: http://llvm.org/viewvc/llvm-project?rev=205889&view=rev
Log:
[ARM64] Fix canonicalisation of MOVs. MOV is too complex to be modelled by a dumb alias.

Modified:
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
    llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
    llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
    llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td Wed Apr  9 09:44:18 2014
@@ -604,13 +604,6 @@ defm ORN  : LogicalReg<0b01, 1, "orn",
                        BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
 defm ORR  : LogicalReg<0b01, 0, "orr", or>;
 
-def : InstAlias<"mov $dst, $src", (ORRWrs GPR32:$dst, WZR, GPR32:$src, 0)>;
-def : InstAlias<"mov $dst, $src",
-                (ADDWri GPR32sp:$dst, GPR32sp:$src, 0, 0)>;
-def : InstAlias<"mov $dst, $src", (ORRXrs GPR64:$dst, XZR, GPR64:$src, 0)>;
-def : InstAlias<"mov $dst, $src",
-                (ADDXri GPR64sp:$dst, GPR64sp:$src, 0, 0)>;
-
 def : InstAlias<"tst $src1, $src2",
                 (ANDSWri WZR, GPR32:$src1, logical_imm32:$src2)>;
 def : InstAlias<"tst $src1, $src2",

Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Wed Apr  9 09:44:18 2014
@@ -3732,9 +3732,9 @@ bool ARM64AsmParser::validateInstruction
   }
 }
 
-static void rewriteMOV(ARM64AsmParser::OperandVector &Operands,
-                       StringRef mnemonic, uint64_t imm, unsigned shift,
-                       MCContext &Context) {
+static void rewriteMOVI(ARM64AsmParser::OperandVector &Operands,
+                        StringRef mnemonic, uint64_t imm, unsigned shift,
+                        MCContext &Context) {
   ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
   ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
   Operands[0] =
@@ -3750,6 +3750,43 @@ static void rewriteMOV(ARM64AsmParser::O
   delete Op;
 }
 
+static void rewriteMOVRSP(ARM64AsmParser::OperandVector &Operands,
+                        MCContext &Context) {
+  ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
+  ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
+  Operands[0] =
+    ARM64Operand::CreateToken("add", false, Op->getStartLoc(), Context);
+
+  const MCExpr *Imm = MCConstantExpr::Create(0, Context);
+  Operands.push_back(ARM64Operand::CreateImm(Imm, Op2->getStartLoc(),
+                                             Op2->getEndLoc(), Context));
+  Operands.push_back(ARM64Operand::CreateShifter(
+      ARM64_AM::LSL, 0, Op2->getStartLoc(), Op2->getEndLoc(), Context));
+
+  delete Op;
+}
+
+static void rewriteMOVR(ARM64AsmParser::OperandVector &Operands,
+                        MCContext &Context) {
+  ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
+  ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
+  Operands[0] =
+    ARM64Operand::CreateToken("orr", false, Op->getStartLoc(), Context);
+
+  // Operands[2] becomes Operands[3].
+  Operands.push_back(Operands[2]);
+  // And Operands[2] becomes ZR.
+  unsigned ZeroReg = ARM64::XZR;
+  if (isGPR32Register(Operands[2]->getReg()))
+    ZeroReg = ARM64::WZR;
+
+  Operands[2] =
+    ARM64Operand::CreateReg(ZeroReg, false, Op2->getStartLoc(),
+                            Op2->getEndLoc(), Context);
+
+  delete Op;
+}
+
 bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
   switch (ErrCode) {
   case Match_MissingFeature:
@@ -3840,6 +3877,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
     // FIXME: Catching this here is a total hack, and we should use tblgen
     // support to implement this instead as soon as it is available.
 
+    ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
     ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
     if (Op2->isImm()) {
       if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op2->getImm())) {
@@ -3856,36 +3894,47 @@ bool ARM64AsmParser::MatchAndEmitInstruc
 
         // MOVK Rd, imm << 0
         if ((Val & 0xFFFF) == Val)
-          rewriteMOV(Operands, "movz", Val, 0, getContext());
+          rewriteMOVI(Operands, "movz", Val, 0, getContext());
 
         // MOVK Rd, imm << 16
         else if ((Val & 0xFFFF0000ULL) == Val)
-          rewriteMOV(Operands, "movz", Val, 16, getContext());
+          rewriteMOVI(Operands, "movz", Val, 16, getContext());
 
         // MOVK Rd, imm << 32
         else if ((Val & 0xFFFF00000000ULL) == Val)
-          rewriteMOV(Operands, "movz", Val, 32, getContext());
+          rewriteMOVI(Operands, "movz", Val, 32, getContext());
 
         // MOVK Rd, imm << 48
         else if ((Val & 0xFFFF000000000000ULL) == Val)
-          rewriteMOV(Operands, "movz", Val, 48, getContext());
+          rewriteMOVI(Operands, "movz", Val, 48, getContext());
 
         // MOVN Rd, (~imm << 0)
         else if ((NVal & 0xFFFFULL) == NVal)
-          rewriteMOV(Operands, "movn", NVal, 0, getContext());
+          rewriteMOVI(Operands, "movn", NVal, 0, getContext());
 
         // MOVN Rd, ~(imm << 16)
         else if ((NVal & 0xFFFF0000ULL) == NVal)
-          rewriteMOV(Operands, "movn", NVal, 16, getContext());
+          rewriteMOVI(Operands, "movn", NVal, 16, getContext());
 
         // MOVN Rd, ~(imm << 32)
         else if ((NVal & 0xFFFF00000000ULL) == NVal)
-          rewriteMOV(Operands, "movn", NVal, 32, getContext());
+          rewriteMOVI(Operands, "movn", NVal, 32, getContext());
 
         // MOVN Rd, ~(imm << 48)
         else if ((NVal & 0xFFFF000000000000ULL) == NVal)
-          rewriteMOV(Operands, "movn", NVal, 48, getContext());
+          rewriteMOVI(Operands, "movn", NVal, 48, getContext());
       }
+    } else if (Op1->isReg() && Op2->isReg()) {
+      // reg->reg move.
+      unsigned Reg1 = Op1->getReg();
+      unsigned Reg2 = Op2->getReg();
+      if ((Reg1 == ARM64::SP && isGPR64Reg(Reg2)) ||
+          (Reg2 == ARM64::SP && isGPR64Reg(Reg1)) ||
+          (Reg1 == ARM64::WSP && isGPR32Register(Reg2)) ||
+          (Reg2 == ARM64::WSP && isGPR32Register(Reg1)))
+        rewriteMOVRSP(Operands, getContext());
+      else
+        rewriteMOVR(Operands, getContext());
     }
   } else if (NumOperands == 4) {
     if (Tok == "add" || Tok == "adds" || Tok == "sub" || Tok == "subs") {

Modified: llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp Wed Apr  9 09:44:18 2014
@@ -52,7 +52,7 @@ void ARM64InstPrinter::printRegName(raw_
 
 void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
                                  StringRef Annot) {
-  // Check for special encodings and print the cannonical alias instead.
+  // Check for special encodings and print the canonical alias instead.
 
   unsigned Opcode = MI->getOpcode();
 
@@ -250,6 +250,38 @@ void ARM64InstPrinter::printInst(const M
     printExtend(MI, 3, O);
     return;
   }
+  // ADD WSP, Wn, #0 ==> MOV WSP, Wn
+  if (Opcode == ARM64::ADDWri && (MI->getOperand(0).getReg() == ARM64::WSP ||
+                                  MI->getOperand(1).getReg() == ARM64::WSP) &&
+      MI->getOperand(2).getImm() == 0 &&
+      ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
+    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
+      << ", " << getRegisterName(MI->getOperand(1).getReg());
+    return;
+  }
+  // ADD XSP, Wn, #0 ==> MOV XSP, Wn
+  if (Opcode == ARM64::ADDXri && (MI->getOperand(0).getReg() == ARM64::SP ||
+                                  MI->getOperand(1).getReg() == ARM64::SP) &&
+      MI->getOperand(2).getImm() == 0 &&
+      ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
+    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
+      << ", " << getRegisterName(MI->getOperand(1).getReg());
+    return;
+  }
+  // ORR Wn, WZR, Wm ==> MOV Wn, Wm
+  if (Opcode == ARM64::ORRWrs && MI->getOperand(1).getReg() == ARM64::WZR &&
+      MI->getOperand(3).getImm() == 0) {
+    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
+      << ", " << getRegisterName(MI->getOperand(2).getReg());
+    return;
+  }
+  // ORR Xn, XZR, Xm ==> MOV Xn, Xm
+  if (Opcode == ARM64::ORRXrs && MI->getOperand(1).getReg() == ARM64::XZR &&
+      MI->getOperand(3).getImm() == 0) {
+    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
+      << ", " << getRegisterName(MI->getOperand(2).getReg());
+    return;
+  }
 
   if (!printAliasInstr(MI, O))
     printInstruction(MI, O);

Modified: llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt?rev=205889&r1=205888&r2=205889&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt Wed Apr  9 09:44:18 2014
@@ -11,3 +11,7 @@
 0x08 0x20 0x21 0x1e
 
 # CHECK: fcmp s0, #0.0
+
+0x1f 0x00 0x00 0x11
+
+# CHECK: mov wsp, w0





More information about the llvm-commits mailing list