[llvm] r363054 - [RISCV] Lower inline asm constraints I, J & K for RISC-V
Lewis Revill via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 11 05:42:13 PDT 2019
Author: lewis-revill
Date: Tue Jun 11 05:42:13 2019
New Revision: 363054
URL: http://llvm.org/viewvc/llvm-project?rev=363054&view=rev
Log:
[RISCV] Lower inline asm constraints I, J & K for RISC-V
This validates and lowers arguments to inline asm nodes which have the
constraints I, J & K, with the following semantics (equivalent to GCC):
I: Any 12-bit signed immediate.
J: Immediate integer zero only.
K: Any 5-bit unsigned immediate.
Differential Revision: https://reviews.llvm.org/D54093
Modified:
llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h
llvm/trunk/test/CodeGen/RISCV/inline-asm.ll
Modified: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp?rev=363054&r1=363053&r2=363054&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp Tue Jun 11 05:42:13 2019
@@ -2151,6 +2151,44 @@ RISCVTargetLowering::getRegForInlineAsmC
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
}
+void RISCVTargetLowering::LowerAsmOperandForConstraint(
+ SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
+ SelectionDAG &DAG) const {
+ // Currently only support length 1 constraints.
+ if (Constraint.length() == 1) {
+ switch (Constraint[0]) {
+ case 'I':
+ // Validate & create a 12-bit signed immediate operand.
+ if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
+ uint64_t CVal = C->getSExtValue();
+ if (isInt<12>(CVal))
+ Ops.push_back(
+ DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT()));
+ }
+ return;
+ case 'J':
+ // Validate & create an integer zero operand.
+ if (auto *C = dyn_cast<ConstantSDNode>(Op))
+ if (C->getZExtValue() == 0)
+ Ops.push_back(
+ DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getXLenVT()));
+ return;
+ case 'K':
+ // Validate & create a 5-bit unsigned immediate operand.
+ if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
+ uint64_t CVal = C->getZExtValue();
+ if (isUInt<5>(CVal))
+ Ops.push_back(
+ DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT()));
+ }
+ return;
+ default:
+ break;
+ }
+ }
+ TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
+}
+
Instruction *RISCVTargetLowering::emitLeadingFence(IRBuilder<> &Builder,
Instruction *Inst,
AtomicOrdering Ord) const {
Modified: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h?rev=363054&r1=363053&r2=363054&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h Tue Jun 11 05:42:13 2019
@@ -93,6 +93,10 @@ public:
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
+ void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
+ std::vector<SDValue> &Ops,
+ SelectionDAG &DAG) const override;
+
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const override;
Modified: llvm/trunk/test/CodeGen/RISCV/inline-asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/inline-asm.ll?rev=363054&r1=363053&r2=363054&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/inline-asm.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/inline-asm.ll Tue Jun 11 05:42:13 2019
@@ -82,4 +82,72 @@ define i32 @constraint_m2(i32* %a) nounw
ret i32 %1
}
+define void @constraint_I() {
+; RV32I-LABEL: constraint_I:
+; RV32I: # %bb.0:
+; RV32I-NEXT: #APP
+; RV32I-NEXT: addi a0, a0, 2047
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: #APP
+; RV32I-NEXT: addi a0, a0, -2048
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_I:
+; RV64I: # %bb.0:
+; RV64I-NEXT: #APP
+; RV64I-NEXT: addi a0, a0, 2047
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: #APP
+; RV64I-NEXT: addi a0, a0, -2048
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+ tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 2047)
+ tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 -2048)
+ ret void
+}
+
+define void @constraint_J() {
+; RV32I-LABEL: constraint_J:
+; RV32I: # %bb.0:
+; RV32I-NEXT: #APP
+; RV32I-NEXT: addi a0, a0, 0
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_J:
+; RV64I: # %bb.0:
+; RV64I-NEXT: #APP
+; RV64I-NEXT: addi a0, a0, 0
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+ tail call void asm sideeffect "addi a0, a0, $0", "J"(i32 0)
+ ret void
+}
+
+define void @constraint_K() {
+; RV32I-LABEL: constraint_K:
+; RV32I: # %bb.0:
+; RV32I-NEXT: #APP
+; RV32I-NEXT: csrwi mstatus, 31
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: #APP
+; RV32I-NEXT: csrwi mstatus, 0
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_K:
+; RV64I: # %bb.0:
+; RV64I-NEXT: #APP
+; RV64I-NEXT: csrwi mstatus, 31
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: #APP
+; RV64I-NEXT: csrwi mstatus, 0
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+ tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 31)
+ tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 0)
+ ret void
+}
+
; TODO: expend tests for more complex constraints, out of range immediates etc
More information about the llvm-commits
mailing list