[LLVMdev] Weird register allocation problem with our target

Rodolphe Suescun rsu.medal at dolphin.fr
Thu Jun 26 04:51:24 PDT 2014


Hi,

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
%vreg19.
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,
Rod




More information about the llvm-dev mailing list