Use not jointly dominated by defs

I can force register allocation to throw the following error message with my target backend:
fatal error: error in backend: Use not jointly dominated by defs.

Source code:

__attribute__((noinline))
int ADD1(int lhs, int rhs)
{
  return lhs + rhs;
}

static int direct_src1;

__attribute__((noinline))
void ADD2()
{
  direct_src1 += 1;
}


int test_main(volatile int* result,
      int argc, const int *argv)
{
  int src1 = argv[0];
  int src2 = argv[1];

  *result = ADD1(src1, src2);

  direct_src1 = argv[1];

  return 0;
}

IR:

# *** IR Dump After Live Register Matrix (liveregmatrix) ***:
# Machine code for function test_main: NoPHIs, TracksLiveness, TiedOpsRewritten, TracksDebugUserValues
Function Live Ins: $r0 in %0, $r2 in %2

0B	bb.0.entry:
	  liveins: $r0, $r2
16B	  %2:rregs = COPY $r2
32B	  %0:rregs = COPY $r0
48B	  undef %6.AX:aidregs = COPY %2:rregs
64B	  %6.INCDEC:aidregs = MV 32
160B	  %9:bregs, %6.AX:aidregs = MV %6.AX:aidregs(tied-def 1), %6.INCDEC:aidregs
176B	  %11:bregs = MV %6.AX:aidregs :: (load (s32) from %ir.arrayidx1, !tbaa !3)
192B	  ADJCALLSTACKDOWN 0, 0, implicit-def dead $a13, implicit $a13
208B	  $r0 = COPY %9:bregs
224B	  $r1 = COPY %11:bregs
240B	  JLR @ADD1, <regmask $r6 $r7 $r8 $r9 $r10 $r11 $r12 $r13 $r14 $r15 $r16 $r17 $r18 $r19 $r28 $r29 $r30 $r31>, implicit-def dead $r31, implicit $r0, implicit killed $r1, implicit-def $a13, implicit-def $r0
256B	  ADJCALLSTACKUP 0, 0, implicit-def dead $a13, implicit $a13
272B	  %12:bregs = COPY $r0
288B	  %13:aregs = COPY %0:rregs
304B	  MV %13:aregs, %12:bregs :: (volatile store (s32) into %ir.result, !tbaa !3)
320B	  %14:bregs = MV %6.AX:aidregs :: (load (s32) from %ir.arrayidx1, !tbaa !3)
336B	  MV @direct_src1, %14:bregs :: (store (s32) into @direct_src1, !tbaa !3)
352B	  %15:bregs = MV 0
368B	  $r0 = COPY %15:bregs
384B	  RETURN implicit $r0

# End machine code for function test_main.

Use of $a13 does not have a corresponding definition on every path:
192r ADJCALLSTACKDOWN 0, 0, implicit-def dead $a13, implicit $a13
fatal error: error in backend: Use not jointly dominated by defs.

Please note:

  1. $a13 is a hard register, it’s the stack-pointer; this should be legal.
  2. the same ADJCALLSTACKDOWN appears in every IR code that calls another function and does not cause any error messages.
  3. when I remove the useless function ADD2, everything goes well

Any hints?
Thanks,
Boris

Your stack pointer should be a reserved register which doesn’t have liveness tracked. It sounds to me like you aren’t reserving it

The stack pointer is a reserved register. In the .td file I use implicit Defs and Uses like all other backends:

let Defs = [ A13 ], Uses = [ A13 ], hasSideEffects = 1, isCodeGenOnly = 1 in {
  def ADJCALLSTACKDOWN:
...

BTW, I use LLVM 14.0.6

Adding the stack pointer to the instruction definition doesn’t make it reserved. I mean the getReservedRegs implementation would need to add the SP to the reserved physical register set

The stack pointer is a reserved register.

The error message is misleading. The mentioned stack pointer a13 is reserved. But registers that contain a13 as a sub-registers were not reserved. After marking these registers as reserved the error was gone.
Thanks.

Right, all aliasing registers of a reserved register must also be reserved

There is checkAllSuperRegsMarked to enforce this.

Thanks arsenm and s-barannikov. I have also noticed the calls to markSuperRegs.