[LLVMdev] PHINode containing itself causes segfault when compiling Blender OpenCL kernel with R600 backend

John Criswell jtcriswel at gmail.com
Mon Sep 22 07:48:47 PDT 2014


On 9/20/14, 5:54 PM, Vitaliy Filippov wrote:
> Hi!
>
> I'm trying to run Blender using Mesa OpenCL implementation on a 
> radeonsi card. First the kernel didn't want to compile, but that was 
> caused by a bug in it (they were using . instead of -> in 1 place), 
> and after fixing this bug I've got the kernel to compile...
>
> ...But after that, LLVM started to crash during translation of IR into 
> shader code with R600 backend.
>
> I've done some investigation and figured out that the crash is caused 
> by a PHINode containing itself. 
> SIAnnotateControlFlow::handleLoopCondition() can't handle such 
> situation - it recurses into itself, calls Phi->eraseFromParent() 
> inside the inner execution, returns into outer one, gets zeroed out 
> object and crashes when trying to do something with its members... for 
> example when trying to erase it again.
>
> I have no real background in LLVM or GCC, so the concept of PHINode 
> itself was a real discovery for me :) and PHINode containing itself 
> does look even more strange... I've tried to understand the semantics 
> of such PHINodes from reading the code and got a suspicion that the 
> rest of LLVM code just ignores PHINodes equal to their parent... So 
> I've tried to fix the bug by making handleLoopCondition() skip 
> IncomingValues equal to the Phi itself, but the bug didn't go away! 
> Surprisingly, PHINode may not just contain itself directly, but it 
> also may contain itself inside another PHINode, i.e. 
> Phi->getIncomingValue(0)->getIncomingValue(0) == Phi, which results in 
> the same problem with SIAnnotateControlFlow...
>
> Besides "how to make a correct fix" :), my question also is: what are 
> the real semantics of a PHINode containing itself directly or 
> indirectly? I've done some tracing and saw such PHINodes added by the 
> optimizer, in llvm::InlineFunction()... but what do they mean and how 
> to deal with them correctly?

If a phi-node contains itself as one of its inputs, then that input will 
contain the last dynamic value of that phi-node (which means, 
essentially, that its value does not change).  If you have:

r1 = phi (bb1, p1) (bb2, r1)

... then if control-flow enters from basic block bb1, then r1 is set to 
the value p1 whereas if control-flow enters from basic block bb2 r1 will 
have its value set to r1 (meaning that it won't change).

For more information on phi-nodes and why they exist, I recommend 
reading "Efficiently computing static single assignment form and the 
control dependence graph" by Ron Cytron et. al.

Regards,

John Criswell




More information about the llvm-dev mailing list