Hi all,
Not sure what sub-category to put this into, although it’s probably AVR
target related, it relates to a feature I’ll probably need to add as one of the (few) contributors to that target, so I think I’ll need wider help!
This IR fails to lower on the AVR platform…
i8* addrspacecast (i8 addrspace(1)* bitcast (void () addrspace(1)* @swift_deletedMethodError to i8 addrspace(1)*) to i8*)
With this error:
LLVM ERROR: Unsupported expression in static initializer: addrspacecast (i8 addrspace(1)* bitcast (void () addrspace(1)* @swift_deletedMethodError to i8 addrspace(1)*) to i8*)
Looking in the code in AsmPrinter.cpp
in lowerConstant
, it looks like the function isNoopAddrSpaceCast
needs to return true…
case Instruction::AddrSpaceCast: {
const Constant *Op = CE->getOperand(0);
unsigned DstAS = CE->getType()->getPointerAddressSpace();
unsigned SrcAS = Op->getType()->getPointerAddressSpace();
if (TM.isNoopAddrSpaceCast(SrcAS, DstAS))
return lowerConstant(Op);
// Fallthrough to error.
LLVM_FALLTHROUGH;
}
I’m trying to understand what this function is/does, to decide how to write the implementation for AVR (there currently isn’t an implementation… AVR only recently left experimental and is still fairly niche).
It seems like the base implementation in TargetMachine.h
returns false, but on many platforms (AArch64, ARM, PPC, RISCV) its hard coded to return true. In some platforms (X86, MIPS) there’s a basic test that the address spaces are not “special types”.
It doesn’t help that I don’t really have much of a concept of what the addrspacecast
instruction is used for in general and what the edge cases are. In my particular case, I’m adding it to a specialised fork of my swift compiler’s IRGen system, what I’m doing is storing an array of various types of i8*
from various sources. Some are from pointers in address space 0, some are from pointers in (program) address space 1. So for me, addspacecast
seems the perfect instruction. I suppose that given that addres spaces for pointers are largely theoretical, really the only thing addspacecast
can ever do is a noop that effectively removes an error (you’re asserting that it’s OK to interpret a pointer value in one address space as a pointer value in another address space)? So the name of the function makes sense.
If I’m right, then it seems to me OK that I add an implementation on our backend to return true from isNoopAddrSpaceCast
, because all you are really saying is “if a compiler developer/user of llvm libraries targeting the AVR platform wants to use the addrspacecast
instruction and they’re sure it’s a good idea, then they are allowed to”. Is that right?
Thanks for any help and advice people!