I've got a call instruction: call void bitcast (void (%4 addrspace(1)*, <2 x i32>, <4 x float>)* @_Z12write_imagefPU3AS110_image2d_tDv2_iDv4_f to void (%9 addrspace(1)*, <2 x i32>, <4 x float>)*)(%9 addrspace(1)* %dstimg, <2 x i32> %28, <4 x float> %26) nounwind %4 and %9 are both (stripped) opaque structs. InlineFunction() does not inline this because call->getCalledFunction() returns 0. call->getCalledValue() returns a cast ConstantExpr. The called Function * is available at (leaving out necessary casts and checks) call->getCalledValue()->getOperand(0). I've tried using call->setCalledFunction(), but that isn't successful either, I'm guessing because the types don't match. If I don't strip the module, the linker produces an ordinary call to the target function, with no bitcast because both formal arg and passed arg have the same opaque struct name, and InlineFunction() works great. Is this a "bug" in InlineFunction? Or is there something I am expected to do to the call before calling InlineFunction()? (If yes, what? ;-) It feels like replacing the call, bitcasting the types of the arguments to match the types expected by the callee, is 'unreasonable'. Note that InlineFunction() also doesn't work if the callee is an alias… and I sure wish that "just worked" as well. ;-) But in that case, calling call->setCalledFunction() is straight forward enough and does work. Thanks, Richard
On Fri, Nov 9, 2012 at 3:25 PM, Relph, Richard <Richard.Relph at amd.com> wrote:> I've got a call instruction: > call void bitcast (void (%4 addrspace(1)*, <2 x i32>, <4 x float>)* @_Z12write_imagefPU3AS110_image2d_tDv2_iDv4_f to void (%9 addrspace(1)*, <2 x i32>, <4 x float>)*)(%9 addrspace(1)* %dstimg, <2 x i32> %28, <4 x float> %26) nounwind > > %4 and %9 are both (stripped) opaque structs. > > InlineFunction() does not inline this because call->getCalledFunction() returns 0. call->getCalledValue() returns a cast ConstantExpr. The called Function * is available at (leaving out necessary casts and checks) call->getCalledValue()->getOperand(0). I've tried using call->setCalledFunction(), but that isn't successful either, I'm guessing because the types don't match. > > If I don't strip the module, the linker produces an ordinary call to the target function, with no bitcast because both formal arg and passed arg have the same opaque struct name, and InlineFunction() works great.This sounds like a bug in the IR linker (which is normally pretty good at unifying struct types).> Is this a "bug" in InlineFunction? Or is there something I am expected to do to the call before calling InlineFunction()? (If yes, what? ;-)instcombine knows how to fix this. -Eli
Eli,
Thanks. I don't think it's a bug in the linker, really… it's
required to treat (stripped) opaque types as different, since it really has no
way to know if the caller and the callee really are referring to the same thing…
though it then seems to turn right around and do exactly that by inserting the
bitcast. ;-) (That does come from the linker.)
That the linker 'works differently' if the modules are not stripped
is arguably a 'bug', since even if the opaque types happen to have the
same name, they still may not be referring to the same type.
That said, I think what the linker is doing with unstripped modules is
reasonable… Using an opaque structure's name to "match" types is
really the only option. And they are, in fact, in this case, referring to the
same type.
I would go a bit further, though, and say that IF the linker is (as it seems
to be) using opaque structure names to match types, then the "strip"
pass ought to leave opaque structure names intact. In this particular case, the
names aren't useless… Or perhaps ALL (stripped) opaque types should merely
be smashed together to avoid the troublesome bitcast.
I'll look in to instcombine, but if you've got any further words of
advice on how to use it, they would be greatly appreciated.
Thanks,
Richard
On Nov 9, 2012, at 3:33 PM, Eli Friedman <eli.friedman at gmail.com>
wrote:
> On Fri, Nov 9, 2012 at 3:25 PM, Relph, Richard <Richard.Relph at
amd.com> wrote:
>> I've got a call instruction:
>> call void bitcast (void (%4 addrspace(1)*, <2 x i32>, <4 x
float>)* @_Z12write_imagefPU3AS110_image2d_tDv2_iDv4_f to void (%9
addrspace(1)*, <2 x i32>, <4 x float>)*)(%9 addrspace(1)* %dstimg,
<2 x i32> %28, <4 x float> %26) nounwind
>>
>> %4 and %9 are both (stripped) opaque structs.
>>
>> InlineFunction() does not inline this because
call->getCalledFunction() returns 0. call->getCalledValue() returns a cast
ConstantExpr. The called Function * is available at (leaving out necessary casts
and checks) call->getCalledValue()->getOperand(0). I've tried using
call->setCalledFunction(), but that isn't successful either, I'm
guessing because the types don't match.
>>
>> If I don't strip the module, the linker produces an ordinary call
to the target function, with no bitcast because both formal arg and passed arg
have the same opaque struct name, and InlineFunction() works great.
>
> This sounds like a bug in the IR linker (which is normally pretty good
> at unifying struct types).
>
>> Is this a "bug" in InlineFunction? Or is there something I am
expected to do to the call before calling InlineFunction()? (If yes, what? ;-)
>
> instcombine knows how to fix this.
>
> -Eli
>
Maybe Matching Threads
- [LLVMdev] Inlining bitcast functions...
- [LLVMdev] Inlining bitcast functions...
- [LLVMdev] Inlining bitcast functions...
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?
- [LLVMdev] [DragonEgg] Why Fortran's "call flush()" is converted to "call void bitcast (void (...)* @_gfortran_flush_i4 to void (i8*)*)(i8* null) nounwind" ?