Aroic
Aroic

Reputation: 479

LLVM Can't cast array type to ConstantArray

I'm trying to cast an array of type [3 x double] to a ConstantArray to eventually change the underlying type from double to float. But whenever I try to cast it fails and I haven't been able to figure out why.

The snippet of code from the pass that is running (edited to add more info):

CallInst& inst; //passed in by function arg
CallInst* oldCall = &inst;
Constant *constant = dyn_cast<Constant>(oldCall->getOperand(1)->stripPointerCasts());
errs() << "Operand is: " << *constant->getOperand(0) << "\n";
errs() << "Operand type: " << *constant->getOperand(0)->getType() << "\n";
ConstantArray *constantArray = cast<ConstantArray>(constant->getOperand(0));

The output:

Operand is: [3 x double] [double 2.100000e+00, double 2.200000e+00, double 2.300000e+00]
Operand type: [3 x double]
opt: /include/llvm/Support/Casting.h:255: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) 
[with X = llvm::ConstantArray; Y = llvm::Value; typename llvm::cast_retty<X, Y*>::ret_type = 
llvm::ConstantArray*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

As can be seen, the operand in our constant is an array type. When trying to cast it sees a Value due to the underlying nature of cast (I think?), but still fails to think they are compatible. Does anyone know why this is?

Note: This is using flang's LLVM release_70 branch, which is just a slightly modified LLVM 7.1.0 library.

Upvotes: 0

Views: 514

Answers (1)

arnt
arnt

Reputation: 9685

You cannot cast an array to anything else, including a different array (AIUI because casting rules are language-specific). The usual approach is to cast a pointer instead, something like this.

auto c = CastInst::Create(CastInst::BitCast,
                          sourcePointerToDoubleArray,
                          ArrayType::get(Type::getFloatTy(), 3)->getPointerto(),
                          "funny_little_ast",
                          targetBasicBlock);

There's also a ConstantExpr::getPointerCast(). Both of these simply reinterpret the bits you point at.

Upvotes: 0

Related Questions