How to pass a constant to f16 in pattern result dag

// Operand Def
def simm16 : Operand<i32>, ImmLeaf<i32, [{return isInt<16>(Imm);}]>;
def fimm16 : Operand<f16>, FPImmLeaf<f16, [{ return true; }]>;
// Instruction Def
def S32TF16 : Instruction {
  let InOperandList = (ins GPR:$rs1, simm16:$imm, fimm16:$immf);
// Pattern
def: Pat<(f16 (sint_to_fp (i32 GPR:$rs1))), (S32TF16 GPR:$rs1, 1, 0)>;

// Complie error
Type set is empty for each HW mode:
possible type contradiction in the pattern below (use -print-records with llvm-tblgen to see all expanded records).
anonymous_4668:         (S32TF16:{ *:[i1 i8 i16 i32 f16 f32] } GPR:{ *:[i1 i8 i16 i32 f16 f32] }:$rs1, 1:{ *:[i32] }, 0:{ *:[] })
Generated from record:
anonymous_4668 {        // Pattern Pat
  dag PatternToMatch = (f16 (sint_to_fp (i32 GPR:$rs1)));
  list<dag> ResultInstrs = [(S32TF16 GPR:$rs1, 1, 0)];
  list<Predicate> Predicates = [];
  int AddedComplexity = 0;
}

The constant arg 0 can not be recognized as a f16;
How to pass a constant to f16 in pattern result dag?

You need to give the output immediate an explicit type, like (f16 0)

It still complie failed with same error output;
I found the code checking the dag args, I did not see any float point args checking;
It looks like just checking the Integer argument;
Doesn’t it support a float number argument?

// Complie error
Type set is empty for each HW mode:
possible type contradiction in the pattern below (use -print-records with llvm-tblgen to see all expanded records).
anonymous_4668:         (S32TF16:{ *:[i1 i8 i16 i32 f16 f32] } GPR:{ *:[i1 i8 i16 i32 f16 f32] }:$rs1, 1:{ *:[i32] }, 0:{ *:[] })
Generated from record:
anonymous_4668 {        // Pattern Pat
  dag PatternToMatch = (f16 (sint_to_fp (i32 GPR:$rs1)));
  list<dag> ResultInstrs = [(S32TF16 GPR:$rs1, 1, (f16 0))];
  list<Predicate> Predicates = [];
  int AddedComplexity = 0;
}
// Error backstack:
#10 0x00000000004ba3db llvm::TypeInfer::ValidateOnExit::~ValidateOnExit() /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:876:1
#11 0x00000000004b2167 llvm::TypeInfer::EnforceInteger(llvm::TypeSetByHwMode&) /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:384:1
#12 0x00000000004c27fb llvm::TreePatternNode::ApplyTypeConstraints(llvm::TreePattern&, bool) /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:2450:12
#13 0x00000000004c3ece llvm::TreePatternNode::ApplyTypeConstraints(llvm::TreePattern&, bool) /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:2674:21
#14 0x00000000004c7ef4 llvm::TreePattern::InferAllTypes(llvm::StringMap<llvm::SmallVector<llvm::TreePatternNode*, 1u>, llvm::MallocAllocator> const*) /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:3054:21
#15 0x00000000004cefe2 llvm::CodeGenDAGPatterns::ParseOnePattern(llvm::Record*, llvm::TreePattern&, llvm::TreePattern&, std::vector<llvm::Record*, std::allocator<llvm::Record*> > const&) /home/nanai/project/de-llvm/llvm/build/../utils/TableGen/CodeGenDAGPatterns.cpp:4242:28
// TreePattern before EnforceInteger:
anonymous_4668:         (S32TF16:{ *:[i1 i8 i16 i32 f16 f32] } GPR:{ *:[i1 i8 i16 i32 f16 f32] }:$rs1, 1:{ *:[i32] }, 0:{ *:[f16] })

You need some kind of cast, but I remember having some troubles using FP imms. I think it’s a waste of time to try to preserve fpimm in the backend. AMDGPU transforms all FP constants into integer constants, and then ignores fpimm from there.

You should be able to use SDNodeXForm that takes some value in a form that DAG doesn’t complain about (maybe the decimal representation of the f16 bits as i32?), and puts it in the output as fp16.

In my case, I need a default argument for the instruction S32TF16, there are two kind pattern for this inst:

  1. this last in_operand is parse from the input dag, it is a immediate num;
  2. the last in_operand is a constant 0;
    for the first pattern, IR dag works well; but for the second pattern, I could not find a usecase to express a defalut value 0 in the output dag;
    Finally, I find zero_reg can be used for a defalut value, and when I emmit asm, I can print 0 for it;
    It work well for me now;