How to implement fneg pat?

I want to use Pat to implement fneg translate. There is no fneg instructions on my backend.

def MovfGR : DSPPseudo<(outs CPUfRegs:$ra), (ins CPUfRegs:$rs, f32imm:$in), "", []>;
def: Pat<(fneg CPUfRegs:$Rs), (FSMUL CPUfRegs:$Rs, (MovfGR CPUfRegs:$Rs, (f32 -1)))>;
//MovfGR is presudo, I will expand it in code, FSMUL is my backend fmul instruction(f32 mul)

But llvm-tablegen generate error like this:

$ ./llvm-tblgen.exe  -gen-instr-info DSP.td
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_2339:         (FSMUL:{ *:[f32] } CPUfRegs:{ *:[f32] }:$Rs, (MovfGR:{ *:[f32] } CPUfRegs:{ *:[f32] }:$Rs, -1:{ *:[] }))
UNREACHABLE executed at D:\git_soft\compiler10\utils\TableGen\CodeGenDAGPatterns.cpp:838!
Stack dump:
0.      Program arguments: C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe -gen-instr-info DSP.td
 #0 0x00007ff6fbfd670c (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x6c670c)
 #1 0x00007ffa6eb5bc31 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6bc31)
 #2 0x00007ffa6eb5d889 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6d889)
 #3 0x00007ff6fbf35a2a (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x625a2a)
 #4 0x00007ff6fba5313e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14313e)
 #5 0x00007ff6fba50153 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x140153)
 #6 0x00007ff6fba5b3bb (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14b3bb)
 #7 0x00007ff6fba5cc20 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14cc20)
 #8 0x00007ff6fba5cc20 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14cc20)
 #9 0x00007ff6fba5dc78 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14dc78)
#10 0x00007ff6fba67369 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x157369)
#11 0x00007ff6fba64f7f (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x154f7f)
#12 0x00007ff6fba61303 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x151303)
#13 0x00007ff6fbde616e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x4d616e)
#14 0x00007ff6fbde60a6 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x4d60a6)
#15 0x00007ff6fbef4c9e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x5e4c9e)
#16 0x00007ff6fc104508 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x7f4508)
#17 0x00007ff6fbef55a0 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x5e55a0)
#18 0x00007ff6fc18c0a9 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87c0a9)
#19 0x00007ff6fc18bf8e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87bf8e)
#20 0x00007ff6fc18be4e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87be4e)
#21 0x00007ff6fc18c13e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87c13e)
#22 0x00007ffabde67034 (C:\Windows\System32\KERNEL32.DLL+0x17034)
#23 0x00007ffabf7e2651 (C:\Windows\SYSTEM32\ntdll.dll+0x52651)

I want to further confirm error, so I modify code like this:

def MovfGR : DSPPseudo<(outs CPUfRegs:$ra), (ins CPUfRegs:$rs, f32imm:$in), "", []>;
def: Pat<(fneg CPUfRegs:$Rs), (MovfGR CPUfRegs:$Rs, (f32 -1))>;// 

but it also generate error like this:

$ ./llvm-tblgen.exe  -gen-instr-info DSP.td
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_2339:         (MovfGR:{ *:[f32] } CPUfRegs:{ *:[f32] }:$Rs, -1:{ *:[] })
UNREACHABLE executed at D:\git_soft\compiler10\utils\TableGen\CodeGenDAGPatterns.cpp:838!
Stack dump:
0.      Program arguments: C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe -gen-instr-info DSP.td
 #0 0x00007ff6fbfd670c (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x6c670c)
 #1 0x00007ffa7055bc31 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6bc31)
 #2 0x00007ffa7055d889 (C:\Windows\SYSTEM32\ucrtbased.dll+0x6d889)
 #3 0x00007ff6fbf35a2a (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x625a2a)
 #4 0x00007ff6fba5313e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14313e)
 #5 0x00007ff6fba50153 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x140153)
 #6 0x00007ff6fba5b3bb (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14b3bb)
 #7 0x00007ff6fba5cc20 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14cc20)
 #8 0x00007ff6fba5dc78 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x14dc78)
 #9 0x00007ff6fba67369 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x157369)
#10 0x00007ff6fba64f7f (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x154f7f)
#11 0x00007ff6fba61303 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x151303)
#12 0x00007ff6fbde616e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x4d616e)
#13 0x00007ff6fbde60a6 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x4d60a6)
#14 0x00007ff6fbef4c9e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x5e4c9e)
#15 0x00007ff6fc104508 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x7f4508)
#16 0x00007ff6fbef55a0 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x5e55a0)
#17 0x00007ff6fc18c0a9 (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87c0a9)
#18 0x00007ff6fc18bf8e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87bf8e)
#19 0x00007ff6fc18be4e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87be4e)
#20 0x00007ff6fc18c13e (C:\Users\wuzhi\Desktop\DSP\llvm-tblgen.exe+0x87c13e)
#21 0x00007ffabde67034 (C:\Windows\System32\KERNEL32.DLL+0x17034)
#22 0x00007ffabf7e2651 (C:\Windows\SYSTEM32\ntdll.dll+0x52651)

My question is:
1.why it is wrong,
2.how can I implement fneg with FSMUL

You’re using an integer for an f32 constant which tablegen doesn’t like.

The deeper problem here is it’s incorrect to implement fneg with an fmul instruction. fmul is a canonicalizing operation and fneg is not. There is a generic fneg expansion in terms of bit operations

en,
I didn’t find f32 imm in other td files. I tried

def: Pat<(fneg CPUfRegs:$Rs), (MovfGR CPUfRegs:$Rs, (f32 -1.0))>;

and get

DSPInstrFPU.td:129:61: error: expected field identifier after '.'
def: Pat<(fneg CPUfRegs:$Rs), (MovfGR CPUfRegs:$Rs, (f32 -1.0))>;

means “fneg” is a SDNode defined in “TargetSelectionDAG.td”, FSMUL is a instruction record, so they can’t pat.

I need use something like?
setOperationAction(ISD::FNEG, MVT::f32, Expand);
or I need:
1.define a Pseudo to select fneg
2.bit operations in some pass, such as PostRAPseudo pass

FP immediate in TableGen are clumsy and I don’t remember exactly what works. AMDGPU just encodes all immediate as integers and just uses the bit values for FP operations.

I mean an instruction that implements fmul does not perform the same operation. Your fmul equivalent instruction is supposed to do things like quiet signaling nans, whereas fneg is a pure bit operation.

You probably should use the setOperationAction for fneg.

Thanks,

It is work.

setOperationAction(ISD::FNEG, MVT::f32, Expand);
setOperationAction(ISD::FNEG, MVT::f64, Expand);

llvm backend expand fneg to fsub

float x = 1;
float y = -(x)// it become 0 - x