From: Lewis Revill Date: Fri, 16 Aug 2019 10:28:34 +0000 (+0000) Subject: [RISCV] Lower inline asm constraint A for RISC-V X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef3be42de9bddffc3ed5e5a2f010c28fda9627ae;p=llvm [RISCV] Lower inline asm constraint A for RISC-V This allows arguments with the constraint A to be lowered to input nodes for RISC-V, which implies a memory address stored in a register. This patch adds the minimal amount of code required to get operands with the right constraints to compile. https://reviews.llvm.org/D54296 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369095 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 2aac807623a..72d8ad1501a 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -244,6 +244,7 @@ public: Constraint_m, Constraint_o, Constraint_v, + Constraint_A, Constraint_Q, Constraint_R, Constraint_S, diff --git a/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index d0a3af375a6..8439278b4ed 100644 --- a/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -179,6 +179,9 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( // operand and need no special handling. OutOps.push_back(Op); return false; + case InlineAsm::Constraint_A: + OutOps.push_back(Op); + return false; default: break; } diff --git a/lib/Target/RISCV/RISCVISelLowering.cpp b/lib/Target/RISCV/RISCVISelLowering.cpp index e822b521fc0..a9c4b69927b 100644 --- a/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2437,6 +2437,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const { case 'J': case 'K': return C_Immediate; + case 'A': + return C_Memory; } } return TargetLowering::getConstraintType(Constraint); @@ -2556,6 +2558,21 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } +unsigned +RISCVTargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const { + // Currently only support length 1 constraints. + if (ConstraintCode.size() == 1) { + switch (ConstraintCode[0]) { + case 'A': + return InlineAsm::Constraint_A; + default: + break; + } + } + + return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); +} + void RISCVTargetLowering::LowerAsmOperandForConstraint( SDValue Op, std::string &Constraint, std::vector &Ops, SelectionDAG &DAG) const { diff --git a/lib/Target/RISCV/RISCVISelLowering.h b/lib/Target/RISCV/RISCVISelLowering.h index f28c4753c1d..e2059e70831 100644 --- a/lib/Target/RISCV/RISCVISelLowering.h +++ b/lib/Target/RISCV/RISCVISelLowering.h @@ -93,6 +93,9 @@ public: const char *getTargetNodeName(unsigned Opcode) const override; ConstraintType getConstraintType(StringRef Constraint) const override; + + unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override; + std::pair getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override; diff --git a/test/CodeGen/RISCV/inline-asm.ll b/test/CodeGen/RISCV/inline-asm.ll index 10f8a3452ab..39403360215 100644 --- a/test/CodeGen/RISCV/inline-asm.ll +++ b/test/CodeGen/RISCV/inline-asm.ll @@ -150,6 +150,31 @@ define void @constraint_K() nounwind { ret void } +define void @constraint_A(i8* %a) nounwind { +; RV32I-LABEL: constraint_A: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: sb s0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: #APP +; RV32I-NEXT: lb s1, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_A: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: sb s0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: #APP +; RV64I-NEXT: lb s1, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret + tail call void asm sideeffect "sb s0, $0", "*A"(i8* %a) + tail call void asm sideeffect "lb s1, $0", "*A"(i8* %a) + ret void +} + define i32 @modifier_z_zero(i32 %a) nounwind { ; RV32I-LABEL: modifier_z_zero: ; RV32I: # %bb.0: