[llvm] b88aba9 - [VE] Support inlineasm memory operand

Kazushi Marukawa via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 22 21:44:14 PDT 2022


Author: Kazushi (Jam) Marukawa
Date: 2022-08-23T13:44:03+09:00
New Revision: b88aba9d7d72adbad2c2c4d1d513bed4f5aa81ad

URL: https://github.com/llvm/llvm-project/commit/b88aba9d7d72adbad2c2c4d1d513bed4f5aa81ad
DIFF: https://github.com/llvm/llvm-project/commit/b88aba9d7d72adbad2c2c4d1d513bed4f5aa81ad.diff

LOG: [VE] Support inlineasm memory operand

Support inline asm memory operand for VE.  Add regression tests also.

Reviewed By: efocht

Differential Revision: https://reviews.llvm.org/D132380

Added: 
    llvm/test/CodeGen/VE/Scalar/inlineasm-mem-gv.ll
    llvm/test/CodeGen/VE/Scalar/inlineasm-mem-lo.ll

Modified: 
    llvm/lib/Target/VE/VEAsmPrinter.cpp
    llvm/lib/Target/VE/VEISelDAGToDAG.cpp
    llvm/lib/Target/VE/VERegisterInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/VE/VEAsmPrinter.cpp b/llvm/lib/Target/VE/VEAsmPrinter.cpp
index 5553087d6f472..03c73a7d966bb 100644
--- a/llvm/lib/Target/VE/VEAsmPrinter.cpp
+++ b/llvm/lib/Target/VE/VEAsmPrinter.cpp
@@ -63,6 +63,8 @@ class VEAsmPrinter : public AsmPrinter {
   void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &OS);
   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                        const char *ExtraCode, raw_ostream &O) override;
+  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+                             const char *ExtraCode, raw_ostream &O) override;
 };
 } // end of anonymous namespace
 
@@ -362,6 +364,9 @@ void VEAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
   case MachineOperand::MO_Register:
     O << "%" << StringRef(getRegisterName(MO.getReg())).lower();
     break;
+  case MachineOperand::MO_Immediate:
+    O << (int)MO.getImm();
+    break;
   default:
     llvm_unreachable("<unknown operand type>");
   }
@@ -389,6 +394,34 @@ bool VEAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
   return false;
 }
 
+bool VEAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+                                         const char *ExtraCode,
+                                         raw_ostream &O) {
+  if (ExtraCode && ExtraCode[0])
+    return true;  // Unknown modifier
+
+  if (MI->getOperand(OpNo+1).isImm() &&
+      MI->getOperand(OpNo+1).getImm() == 0) {
+    // don't print "+0"
+  } else {
+    printOperand(MI, OpNo+1, O);
+  }
+  if (MI->getOperand(OpNo).isImm() &&
+      MI->getOperand(OpNo).getImm() == 0) {
+    if (MI->getOperand(OpNo+1).isImm() &&
+        MI->getOperand(OpNo+1).getImm() == 0) {
+      O << "0";
+    } else {
+      // don't print "(0)"
+    }
+  } else {
+    O << "(";
+    printOperand(MI, OpNo, O);
+    O << ")";
+  }
+  return false;
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmPrinter() {
   RegisterAsmPrinter<VEAsmPrinter> X(getTheVETarget());

diff  --git a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
index a4319ec1c975a..15fd25747ecef 100644
--- a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
@@ -142,6 +142,12 @@ class VEDAGToDAGISel : public SelectionDAGISel {
   bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
   bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);
 
+  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
+  /// inline asm expressions.
+  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
+                                    unsigned ConstraintID,
+                                    std::vector<SDValue> &OutOps) override;
+
   StringRef getPassName() const override {
     return "VE DAG->DAG Pattern Instruction Selection";
   }
@@ -380,6 +386,33 @@ void VEDAGToDAGISel::Select(SDNode *N) {
   SelectCode(N);
 }
 
+/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
+/// inline asm expressions.
+bool
+VEDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
+                                             unsigned ConstraintID,
+                                             std::vector<SDValue> &OutOps) {
+  SDValue Op0, Op1;
+  switch (ConstraintID) {
+  default:
+    llvm_unreachable("Unexpected asm memory constraint");
+  case InlineAsm::Constraint_o:
+  case InlineAsm::Constraint_m: // memory
+    // Try to match ADDRri since reg+imm style is safe for all VE instructions
+    // with a memory operand.
+    if (selectADDRri(Op, Op0, Op1)) {
+      OutOps.push_back(Op0);
+      OutOps.push_back(Op1);
+      return false;
+    }
+    // Otherwise, require the address to be in a register and immediate 0.
+    OutOps.push_back(Op);
+    OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
+    return false;
+  }
+  return true;
+}
+
 SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
   Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
   return CurDAG

diff  --git a/llvm/lib/Target/VE/VERegisterInfo.cpp b/llvm/lib/Target/VE/VERegisterInfo.cpp
index 397ea09c9a024..1c1ffb4c9eada 100644
--- a/llvm/lib/Target/VE/VERegisterInfo.cpp
+++ b/llvm/lib/Target/VE/VERegisterInfo.cpp
@@ -121,6 +121,7 @@ static unsigned offsetToDisp(MachineInstr &MI) {
   {
     using namespace llvm::VE;
     switch (MI.getOpcode()) {
+    case INLINEASM:
     case RRCAS_multi_cases(TS1AML):
     case RRCAS_multi_cases(TS1AMW):
     case RRCAS_multi_cases(CASL):

diff  --git a/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-gv.ll b/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-gv.ll
new file mode 100644
index 0000000000000..1977b928a70bb
--- /dev/null
+++ b/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-gv.ll
@@ -0,0 +1,17 @@
+; RUN: llc < %s -mtriple=ve | FileCheck %s
+
+ at A = dso_local global i64 0, align 8
+
+define i64 @leam(i64 %x) nounwind {
+; CHECK-LABEL: leam:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    lea %s0, A at lo
+; CHECK-NEXT:    and %s0, %s0, (32)0
+; CHECK-NEXT:    lea.sl %s0, A at hi(, %s0)
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    lea %s0, (%s0)
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    b.l.t (, %s10)
+  %asmtmp = tail call i64 asm "lea $0, $1", "=r,*m"(i64* elementtype(i64) @A) nounwind
+  ret i64 %asmtmp
+}

diff  --git a/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-lo.ll b/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-lo.ll
new file mode 100644
index 0000000000000..4f12822c8557d
--- /dev/null
+++ b/llvm/test/CodeGen/VE/Scalar/inlineasm-mem-lo.ll
@@ -0,0 +1,14 @@
+; RUN: llc < %s -mtriple=ve | FileCheck %s
+
+define i64 @leam(i64 %x) nounwind {
+; CHECK-LABEL: leam:
+; CHECK:       .LBB{{[0-9]+}}_2:
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    lea %s0, 8(%s11)
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    adds.l %s11, 16, %s11
+; CHECK-NEXT:    b.l.t (, %s10)
+  %z = alloca i64, align 8
+  %asmtmp = tail call i64 asm "lea $0, $1", "=r,*m"(i64* elementtype(i64) %z) nounwind
+  ret i64 %asmtmp
+}


        


More information about the llvm-commits mailing list