The predicates I set do not work

There is my diff.But when i run ./llvm-mc test -triple=riscv64 -show-encoding, the mvin still be recognized,i wish use -mattr=+mvin before it is recognized.I don’t know why,I think def HasMvin : Predicate<"Subtarget->hasMvin()">; is wrong,but i do not know how to change it.Is there a tablegen print function just like printf in c here? I want to see the corresponding value when llvm-mc runs. If anyone can help me, I would be grateful.

diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 32cbd479bea3..f981f87d41d6 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -12,11 +12,6 @@ include "llvm/Target/Target.td"
 // RISC-V subtarget features and instruction predicates.
 //===----------------------------------------------------------------------===//

-def FeatureMvin
-    : SubtargetFeature<"mvin", "HasMvin", "true", "test mvin">;
-
-def HasMvin : Predicate<"Subtarget->hasMvin()">;
-
 def FeatureStdExtM
     : SubtargetFeature<"m", "HasStdExtM", "true",
                        "'M' (Integer Multiplication and Division)">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 777ff33f6b30..0af53bb63c9e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -598,10 +598,6 @@ class Priv_rr<string opcodestr, bits<7> funct7>
 // Instructions
 //===----------------------------------------------------------------------===//

-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Predicates = [HasMvin] in
-def mvin : RVInstR<0b0000000, 0b000, OPC_CUSTOM_0,(outs GPR:$rd),
-                     (ins GPR:$rs1,GPR:$rs2), "mvin","$rd, $rs1">;
-
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index c0d25ddd6f15..066ad3f55055 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -44,7 +44,6 @@ private:

   RISCVProcFamilyEnum RISCVProcFamily = Others;

-  bool HasMvin = false;
   bool HasStdExtM = false;
   bool HasStdExtA = false;
   bool HasStdExtF = false;
@@ -155,7 +154,6 @@ public:
   /// initializeProperties().
   RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }

-  bool hasMvin() const { return HasMvin; }
   bool hasStdExtM() const { return HasStdExtM; }
   bool hasStdExtA() const { return HasStdExtA; }
   bool hasStdExtF() const { return HasStdExtF; }

I think Predicate only applies to instruction selection patterns, if you want to constrain the assembler too you also have to make HasMVIN an instance of AssemblerPredicate.

It’s because when doing just assembly only the MCWhatever classes are around, there is no RISCVSubtarget to inspect.

Oh! I probably understand, but there is a new question, where is the Subtarget, why does Predicate<"Subtarget->hasMvin()">; not report an error,thanks!.

It’s kind of like an unused variable. What you’ve written is perfectly valid and will correctly set fields in the RISCVSubtarget. It’s just that you haven’t written anything that actually makes use of the Predicate part of that definition.

It would get used if you wrote a pattern for CodeGen to use:

let Requires = [HasMVIN] in
def : Pat<(some_dag GPR:$rs1, GPR:$rs2), (mvin $rs1, $rs2)>;
1 Like

I really appreciate your enthusiasm to help me, I would like to ask some more questions, what is MCWhatever? I didn’t find it on Google, I’m interested in llvm backend implementation, is there a good way to sort out the logic of llvm backend code here.

Ah, sorry, I meant a shorthand for the whole “MC” layer of classes that deal with low level object files and assembly: the classes in this directory.

They can be created without creating any of the bits needed for IR or CodeGen so that’s what pure assemblers like llvm-mc do.

Thanks!

Oh!I may have to bother you again.When i run the llc,llc does not recognize llvm.riscv.mvin.
llc cann’t lower llvm.riscv.mvin to mvin.
Here is my .ll file.I think llvm.riscv.mvin is wrongly written.But I’m not sure.

declare void @llvm.riscv.mvin.i64(i64 %a, i64 %b)

define void  @movein(i64 %a, i64 %b) nounwind {
  call void @llvm.riscv.mvin.i64(i64 %a, i64 %b)
  ret void 
}

Here is my diff.

diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td
index 002920a2e194..1bf2e5615763 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -1582,3 +1582,4 @@ def int_riscv_sm4ed      : ScalarCryptoByteSelectAny;
 def int_riscv_sm3p0      : ScalarCryptoGprIntrinsicAny;
 def int_riscv_sm3p1      : ScalarCryptoGprIntrinsicAny;
 } // TargetPrefix = "riscv"
+def int_riscv_mvin : Intrinsic<[llvm_any_ty],[LLVMMatchType<0>, LLVMMatchType<0>],[IntrNoMem]>;
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 3f42886acc52..e4a9a4c9ed7f 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -12,6 +12,11 @@ include "llvm/Target/Target.td"
 // RISC-V subtarget features and instruction predicates.
 //===----------------------------------------------------------------------===//

+def FeatureMvin
+    : SubtargetFeature<"mvin", "HasMvin", "true", "test mvin">;
+
+def HasMvin : Predicate<"Subtarget->hasMvin()">, AssemblerPredicate<(all_of FeatureMvin), "buddy">;
+
 def FeatureStdExtM
     : SubtargetFeature<"m", "HasStdExtM", "true",
                        "'M' (Integer Multiplication and Division)">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 0af53bb63c9e..65ada8b26bb5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -598,6 +598,10 @@ class Priv_rr<string opcodestr, bits<7> funct7>
 // Instructions
 //===----------------------------------------------------------------------===//

+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Predicates = [HasMvin] in
+def mvin : RVInstR<0b0000000, 0b000, OPC_CUSTOM_0,(outs GPR:$rd),
+                     (ins GPR:$rs1,GPR:$rs2), "mvin","$rd, $rs1">;
+
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
@@ -1798,3 +1802,6 @@ include "RISCVInstrInfoZicbo.td"
 //===----------------------------------------------------------------------===//

 include "RISCVInstrInfoXVentana.td"
+
+let Predicates = [HasMvin] in
+def: PatGprGpr<int_riscv_mvin, mvin>;
\ No newline at end of file
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index ddfbea7b0474..4a60eb33cbb6 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -44,6 +44,7 @@ private:

   RISCVProcFamilyEnum RISCVProcFamily = Others;

+  bool HasMvin = false;
   bool HasStdExtM = false;
   bool HasStdExtA = false;
   bool HasStdExtF = false;
@@ -155,6 +156,7 @@ public:
   /// initializeProperties().
   RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }

+  bool hasMvin() const { return HasMvin; }
   bool hasStdExtM() const { return HasStdExtM; }
   bool hasStdExtA() const { return HasStdExtA; }
   bool hasStdExtF() const { return HasStdExtF; }

There are a couple of reasons llc isn’t recognizing it.

  1. It should be inside that let TargetPrefix = "riscv" block just above since it’s a RISC-V intrinsic.
  2. In IntrinsicsRISCV.td you say that the intrinsic returns the same type as its two arguments, but in the .ll file you declare it as returning void. This is inconsistent, and I assume it really does need to return something because it doesn’t appear to be a memory operation.

Also, the definition of the instruction is a bit weird. You’ve got 3 registers there, but only two go into the assembly string, I’d expect to see "$rd, $rs1, $rs2" for a basic 3-reg instruction like that.

1 Like

Thanks!I only use two registers, each of which stores an address, one for the cpu and the other for the coprocessor address,i want to extend the back-end to do something interesting.