how can I create an SSE instrinsics sqrt?

I want to create a vector version sqrt as the following.

Value Approx::CreateFSqrt(IRBuilder<> &builder, Value v, const char Name) {
Type tys[] = {v->getType()};
Module
M = currF->getParent();
Value
sqrtv = Intrinsic::getDeclaration(M, Intrinsic::x86_sse2_sqrt_pd);
CallInst *CI = builder.CreateCall(sqrtv, v, Name);

return CI;
}

Here is Value *v is <2 x double>
However, it outputs Assertion `isa(Val) && "cast() argument of incompatible type! any idea?

Hi zhi,

You have to also pass the value type to getDecalaration() API such as

Value* sqrtv = Intrinsic::getDeclaration(M, Intrinsic::x86_sse2_sqrt_pd, v->getType());

Regards,

Shahid

Thanks, Shahid. It is fixed now.

However, there is a new problem now. I can load the pass and use the CreateFSqrt to create a new vector version sqrt.

%vsqrt = call <2 x double> @llvm.x86.sse2.sqrt.pd.v2f64(<2 x double> %1)

However, if I use the %vsqrt in the later instruction %add1 = fadd <2 x double> %vsqrt, <2 x double> %2, I will get the following error:

%vsqrt = callopt: …/llvm-3.3.src/include/llvm/Support/Casting.h:237: typename llvm::enable_if<llvm::is_same<Y, typename llvm::simplify_type::SimpleType>, typename llvm::cast_retty<X, Y*>::ret_type>::type llvm::cast(Y*) [with X = llvm::PointerType; Y = llvm::Type; typename llvm::enable_if<llvm::is_same<Y, typename llvm::simplify_type::SimpleType>, typename llvm::cast_retty<X, Y*>::ret_type>::type = llvm::PointerType*]: Assertion `isa(Val) && “cast() argument of incompatible type!”’ failed. Any hint about this error?

Thanks,
Zhi

It seems that the problem is because the method I used to create the vector version sqrt cannot pass the intrinsics verification pass. Any hint about what’s wrong with the method to create the sqrt intrinsics? Thanks.

Best,
Zhi