[LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.

Vincent Lejeune vljn at ovi.com
Thu Oct 25 08:35:25 PDT 2012


Thank for your answer.
If I set EnableJoining to false  (ie moreless disable the regcoalescer pass), my shader is correct (but with many uneeded MOV) :

BB#0: derived from LLVM BB %0
    Live Ins: %T1_X %T1_Y %T1_Z %T1_W
%T2_Y<def> = MOV 1, 0, 0, 0, %C1_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T3_X<def> = MOV 1, 0, 0, 0, %T1_X<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T3_XYZW<imp-def>
%T2_X<def> = MOV 1, 0, 0, 0, %C1_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T4_X<def> = MOV 1, 0, 0, 0, %T2_Y<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T3_Y<def> = MOV 1, 0, 0, 0, %T1_Y<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T3_XYZW<imp-def>
%T4_Y<def> = MOV 1, 0, 0, 0, %T2_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T1_X<def> = MOV 1, 0, 0, 0, %C1_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T3_Z<def> = MOV 1, 0, 0, 0, %T1_Z<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T3_XYZW<imp-def>
%T4_Z<def> = MOV 1, 0, 0, 0, %T1_X<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T1_X<def> = MOV 1, 0, 0, 0, %C1_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T4_W<def> = MOV 1, 0, 0, 0, %T1_X<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T3_W<def> = MOV 1, 0, 0, 0, %T1_W<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T3_XYZW<imp-def>
%T1_W<def> = MOV 1, 0, 0, 0, %ALU_LITERAL_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_X<def> = MOV 1, 0, 0, 0, %C0_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_Y<def> = MOV 1, 0, 0, 0, %T2_X<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_X<def> = MOV 1, 0, 0, 0, %T4_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T2_Y<def> = MOV 1, 0, 0, 0, %T4_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T2_Z<def> = MOV 1, 0, 0, 0, %T4_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T2_W<def> = MOV 1, 0, 0, 0, %T4_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
WHILELOOP
%T1_Z<def> = MOV 1, 0, 0, 0, %T1_Y<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T4_X<def> = MOV 1, 0, 0, 0, %T2_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T4_Y<def> = MOV 1, 0, 0, 0, %T2_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T4_Z<def> = MOV 1, 0, 0, 0, %T2_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T4_W<def> = MOV 1, 0, 0, 0, %T2_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T4_XYZW<imp-def>
%T1_Y<def> = MOV 1, 0, 0, 0, %T1_W<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_W<def> = SETGT_INT 0, 0, 1, 0, 0, 0, %T1_X, 0, 0, 0, %T1_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%PREDICATE_BIT<def> = PRED_SETE_INT 1, 0, 0, 0, 0, 0, %T1_W, 0, 0, 0, %ZERO, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
BREAK_LOGICALZ_i32 %PREDICATE_BIT
%T1_W<def> = MOV 1, 0, 0, 0, %T4_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_X<def> = MOV 1, 0, 0, 0, %T1_W<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T1_W<def> = MOV 1, 0, 0, 0, %T4_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_Y<def> = MOV 1, 0, 0, 0, %T1_W<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T2_Z<def> = MOV 1, 0, 0, 0, %T1_Z<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T1_Z<def> = MOV 1, 0, 0, 0, %T4_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_W<def> = MOV 1, 0, 0, 0, %T1_Z<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0, %T2_XYZW<imp-def>
%T1_Z<def> = MOV 1, 0, 0, 0, %T4_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_W<def> = MOV 1, 0, 0, 0, %ALU_LITERAL_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 1
%T1_W<def> = ADD_INT 0, 0, 1, 0, 0, 0, %T1_Y<kill>, 0, 0, 0, %T1_W<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_Y<def> = MOV 1, 0, 0, 0, %T1_Z<kill>, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
ENDLOOP
%T2_X<def> = MOV 1, 0, 0, 0, %T4_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_Y<def> = MOV 1, 0, 0, 0, %T4_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_Z<def> = MOV 1, 0, 0, 0, %T4_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T2_W<def> = MOV 1, 0, 0, 0, %T4_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_X<def> = MOV 1, 0, 0, 0, %T3_X, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_Y<def> = MOV 1, 0, 0, 0, %T3_Y, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_Z<def> = MOV 1, 0, 0, 0, %T3_Z, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
%T1_W<def> = MOV 1, 0, 0, 0, %T3_W, 0, 0, 0, 1, pred:%PRED_SEL_OFF, 0
RETURN %T1_W<imp-use>, %T1_Z<imp-use>, %T1_Y<imp-use>, %T1_X<imp-use>, %T2_W<imp-use>, %T2_Z<imp-use>, %T2_Y<imp-use>, %T2_X<imp-use>


This makes me think that the bug is inside llvm.
If I understand your point, it might be inside the phielim pass ? I don't know if I can disable it to track down what's happening (I'm not sure following pass can handle phi properly)

Vincent


>> 
>> 
>>  Apparently, the pass assumed that it's still in SSA mode, and join 
> vreg6 with vreg27, thus ignoring the body block that can modify vreg48 value, 
> and thus vreg6 value.
>>  I don't know if I should manually tell the pass that it's not in 
> SSA mode (I assume that previous pass like 2 address simplification pass does 
> it), if I miss something in my LLVM IR,
>>  or if it's a bug.
> 
> PHIElim and TwoAddress passes leave SSA form.
> May be a missed something in your code but %vreg48 seems to be there 
> after PHI elimination. PHIElim tags those kind of registers as being 
> PHIJoin regs, updating LiveVariables pass, so the regcoalescer is aware 
> of them (some SSA info is still alive but the reg coalescer will 
> invalidate that information after joining intervals). PHIJoin regs 
> doesn't get modified by any other instruction than copies.
> Anyway, IMHO if your code is faulty there should be a bug somewhere else.
> 
> Ivan
> 
>> 





More information about the llvm-dev mailing list