Hi Eli,
Thank you very much for your response.
In fact, I had already tried the X86 approach before, i.e explicitly using the status register. This is the approach that appeals more to me. I left it parked because it also produced some problems (but I left it commented out). So I have now re-lived the code, and it works fine in most cases, but there’s a particular case that causes LLVM to stop with an assertion. Apparently LLVM tries to use the SR (Status Register) register as a general purpose one, which is not allowed in my architecture. The problem exists even before I added the referred optimisations. The code that causes the problem is this:
int doSmth( int y );
int test( int y )
{
int neg = y < 0;
if ( neg )
y = - y;
int rv = doSmth( y );
return neg ? - rv : rv;
}
Apparently, LLVM attempts to physically use the result of a CMP instruction through a function call by storing it on a temporary register. This is found before the doSmth function call,
t30: i16 = CMPkr16 t4, TargetConstant:i16<0>
t36: ch,glue = CopyToReg t0, Register:i16 $sr, t30
t32: i16 = NEGSETCC TargetConstant:i16<4>, t36:1
And this is generated after the call
t35: ch,glue = CopyToReg t0, Register:i16 $sr, t30
t31: i16 = SELCC t19, t18, TargetConstant:i16<4>, t35:1
t21: ch,glue = CopyToReg t18:1, Register:i16 $r0, t31
NEGSETCC and SELCC are genuine instructions of my target architecture, they use the SR along with operands to produce a result.
As you can see ‘t30’ is used both before and after the function call, which is what I think that causes trouble. In particular, the assertion that I get is this:
Assertion failed: (RegClass->isAllocatable() && "Virtual register RegClass must be allocatable."), function createVirtualRegister, file /Users/joan/LLVM+CLANG/llvm-7.0.1.src/lib/CodeGen/MachineRegisterInfo.cpp, line 170.
If I remove the ‘isAllocatable=0’ setting on the SR register, then LLVM will try to spill the SR by calling ‘storeRegToStackSlot’, which then I stop with my own assertion because the SR can’t be spilled.
If I then remove also the ‘let CopCost = -1’ for the SR register, then LLVM attempts to move it to a general purpose register by calling ‘copyPhysRegs’, which again I stop with an assertion because it’s not legal in my architecture.
So, I’m stuck as well with this approach.
Any ideas, on what I can try?
I think, that at this point I need to stop LLVM from attempting to reuse the result of the CMP instruction before and after the function call, and instead make it generate a new cmp instruction after the call. But how do I achieve that?
(maybe a difficulty is that I am Custom lowering ’’SELECT_CC’ and ‘BR_CC’, and Expanding ’SELECT’ and ‘BRCOND’, instead of the opposite? Does this make a difference?)
Thanks
Joan Lluch
Tel: 620 28 45 13