Weird register allocation problem with our target


We have a very strange problem that seems to occur during the
"Virtual Register Rewriter" pass. The problem shows when
compiling a simple "matrix-product-like function" so I'm sure
it is caused by a stupid bug in our target.

The C code where the problem occurs is a simple "for" loop:

     for (k = 0; k < N; ++k) {

The IR for "k < N; ++k" before virtual register rewriter is
the following (%vreg45 is k, %vreg19 is N):

1216B BB#5: derived from LLVM BB %for.inc19
      Predecessors according to CFG: BB#4
1232B MOV_atDRkd_DRks %vreg31, %vreg49; mem:ST4[%sunkaddr12] (align=1)(tbaa=<badref>) DREGS_R:%vreg31 DREGS_WR:%vreg49
1264B %vreg44<def,tied1> = ADD_DRkd_0data16 %vreg44<tied0>, 2, %PSW<imp-def,dead>; DREGS:%vreg44
1296B %vreg45<def,tied1> = ADD_DRkd_0data16 %vreg45<tied0>, 1, %PSW<imp-def,dead>; DREGS:%vreg45
1312B CMP_DRkd_DRks %vreg45, %vreg19, %PSW<imp-def>; DREGS:%vreg45 DREGS_R:%vreg19
1360B JNE_rel <BB#3>, %PSW<imp-use,kill>
1376B SJMP_rel <BB#6>
      Successors according to CFG: BB#6(4) BB#3(124)

The IR after virtual register rewriter is:

1216B BB#5: derived from LLVM BB %for.inc19
      Live Ins: %DR12 %DR28
      Predecessors according to CFG: BB#4
1224B %DR0<earlyclobber,def> = MOV_DRk_atDRkplusdis16 <fi#9>, 0; mem:LD4[FixedStack9](align=1)
1232B MOV_atDRkd_DRks %DR0<kill>, %DR28<kill>; mem:ST4[%sunkaddr12](align=1)(tbaa=<badref>)
1256B %DR16<earlyclobber,def> = MOV_DRk_atDRkplusdis16 <fi#7>, 0; mem:LD4[FixedStack7](align=1)
1264B %DR16<def,tied1> = ADD_DRkd_0data16 %DR16<kill,tied0>, 2, %PSW<imp-def,dead>
1288B %DR0<earlyclobber,def> = MOV_DRk_atDRkplusdis16 <fi#8>, 0; mem:LD4[FixedStack8](align=1)
1296B %DR0<def,tied1> = ADD_DRkd_0data16 %DR0<kill,tied0>, 1, %PSW<imp-def,dead>
1304B %DR0<earlyclobber,def> = MOV_DRk_atDRkplusdis16 <fi#2>, 0; mem:LD4[FixedStack2](align=1)
1312B CMP_DRkd_DRks %DR0, %DR4, %PSW<imp-def>
1360B JNE_rel <BB#3>, %PSW<imp-use,kill>
1376B SJMP_rel <BB#6>
      Successors according to CFG: BB#6(4) BB#3(124)

Line "1312B" shows that DR0 is used for %vreg45 and DR4 is used for
The problem is in line "1304B" where the value of "N" is copied (from
the stack) to the wrong register (DR0 instead of DR4).

Note the problem "disappears" (i.e. is still there but does not
occur) if we change the allocator from greedy to basic, or modify
the compiled code to affect register allocation.

Does anyone have an idea about which part of our target we should
take a close look at, or how to investigate and fix this problem ?
I can give more details about our target if needed (but not sure
which ones would be relevant).

Thanks a lot in advance,