Hi there,
I am currently trying to create an LLVM Backend for a RISC architecture
and running into problems with setCC and brcond.
First a few explanations:
The architecture doesn't have a dedicated flag register, but seven
1-bit-wide so called "condition registers", c0-c6,
which can be set by e.g. a compare instruction:
cmp ne, c0, r1, 123
It also supports conditional execution of _all_ instructions. This,
however, is also the only way to perform a conditional branch:
c7 cmp ne, c0, r1, 123
c0 br $destination
Meaning: the branch instruction will be executed, if c0 (set by previous
instruction) holds a non-zero value.
I tried to model this through a special RegisterClass "CondRegs":
def C0 : CReg< 0, "c0">, DwarfRegNum<[32]>;
[...]
def C7 : CReg< 7, "c7">, DwarfRegNum<[39]>;
def CondRegs : RegisterClass<"MXM", [i1], 32,
(add C0, C1, C2, C3, C4, C5, C6,
C7)>; // C7 = constant one
and by expanding SELECT_CC to SETCC and BR_CC to BRcond.
In my IntstrInfo description, I have the following patterns:
//cmp (setcc) instruction
def CMPri : F1<0b0000001101, (outs CondRegs:$cd), (ins GPRegs:$rn,
uimm8:$uimm8),
"c7 cmp\tne, $cd, $rn, $uimm8",
[(set CondRegs:$cd, (setne GPRegs:$rn, uimmZExt8:$uimm8))]>;
//conditional branch
def BRcondrel : F3_1<0b011110,
(outs), (ins CondRegs:$cd, brtarget:$offset),
"$cd br\t$offset",
[(brcond CondRegs:$cd, bb:$offset)]>;
I want to place the setcc result in a condition reg and then do the
conditional branch with the result from the condition reg.
Unfortunately, this doesn't work. The Instruction Selection itself does
work, but in a later pass the compare and branch instructions are deleted:
DeadMachineInstructionElim: DELETING: BRrel <BB#3>
DeadMachineInstructionElim: DELETING: BRrel <BB#1>
DeadMachineInstructionElim: DELETING: BRcondrel %vreg1<kill>, <BB#2>;
CondRegs:%vreg1
DeadMachineInstructionElim: DELETING: %vreg1<def> = CMPri %vreg0, 0;
CondRegs:%vreg1 GPRegs:%vreg0
What am I missing?
I attached the llc debug output.
Thanks in advance,
Jan Tlatlik
debug.txt (46.6 KB)