Hello, I'm getting the impression that I'm misunderstanding something about intrinsics. I have the following reduced testcase in mind: declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind define void @foo(i8* %a, i8* %b, i32 %c, i32 %d) { entry: ;call void @llvm.memcpy.i32( i8* %a, i8* %b, i32 %c, i32 %d ) ;call void @llvm.memcpy.i32( i8* %a, i8* %b, i32 0, i32 0 ) ret void } I compile this with llvm-as memcpy-intrinsic.ll -f -o memcpy-intrinsic.bc && llc -f -o memcpy-intrinsic.s memcpy-intrinsic.bc Now, if I uncomment the lowermost memcpy, this produces no errors. If I uncomment the uppermost memcpy instead, I get during lcc: llc: /var/bcoppens/llvm/llvm-svn/llvm/include/llvm/Support/Casting.h:199: typename llvm::cast_retty<To, From>::ret_type llvm::cast(const Y&) [with X = llvm::ConstantInt, Y = llvm::Value*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed. I can't see why this would happen. Both times, the function signature I call is seemingly correct to my eyes. Does anybody see what I'm missing here? Thanks, Bart Coppens
Hi,> I'm getting the impression that I'm misunderstanding something about > intrinsics. I have the following reduced testcase in mind: > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind > > define void @foo(i8* %a, i8* %b, i32 %c, i32 %d) { > entry: > ;call void @llvm.memcpy.i32( i8* %a, i8* %b, i32 %c, i32 %d )I'm pretty sure that the alignment argument has to be a constant. Ciao, Duncan.
Hi Bart, I guess that's because the value of the last argument of llvm.memcpy has to be known at compile time. Nicolas Bart Coppens wrote:> Hello, > > I'm getting the impression that I'm misunderstanding something about > intrinsics. I have the following reduced testcase in mind: > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind > > define void @foo(i8* %a, i8* %b, i32 %c, i32 %d) { > entry: > ;call void @llvm.memcpy.i32( i8* %a, i8* %b, i32 %c, i32 %d ) > ;call void @llvm.memcpy.i32( i8* %a, i8* %b, i32 0, i32 0 ) > ret void > } > > I compile this with > > llvm-as memcpy-intrinsic.ll -f -o memcpy-intrinsic.bc && llc -f -o > memcpy-intrinsic.s memcpy-intrinsic.bc > > Now, if I uncomment the lowermost memcpy, this produces no errors. If I > uncomment the uppermost memcpy instead, I get during lcc: > > llc: /var/bcoppens/llvm/llvm-svn/llvm/include/llvm/Support/Casting.h:199: > typename llvm::cast_retty<To, From>::ret_type llvm::cast(const Y&) [with X = > llvm::ConstantInt, Y = llvm::Value*]: Assertion `isa<X>(Val) && "cast<Ty>() > argument of incompatible type!"' failed. > > I can't see why this would happen. Both times, the function signature I call > is seemingly correct to my eyes. Does anybody see what I'm missing here? > > Thanks, > Bart Coppens > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Hi Nicolas,> I guess that's because the value of the last argument of llvm.memcpy has > to be known at compile time.Hmmm ok, that's understandable, but it's also a bit of a problem for me. I am writing a pass that creates a 'shadow' copy of each function, so that I can do some bookkeeping with it, and then call the original function afterwards. This would include intrinsics like memcpy. Now, would it be possible to programmatically determine which arguments are required to be constants? Then I would be able to partially evaluate my custom function, so that multiple versions would be emitted, each with the right constants in their call to memcpy. (Given that LLVM seems to be pretty statically typed, it's rather confusing that this kind of restriction isn't at least annotated in the user-visible type, or isn't noticed by llvm-as.) Thanks, Bart Coppens