Backend Marking Registers as Pointer Only


I've been working on a llvm backend for an architecture that is
predominantly 16-bit but has 32-bit registers exclusively for
load/store operations (in addrspace 1), but I'm having issues with
code generation when the 32-bit registers are enabled.

Without enabling the 32-bit registers (i.e. with addRegisterClass in
ArchTargetLowering constructor) the backend generates valid code for
16-bit pointers, but with 32-bit pointers legalization fails because
the compiler doesn't know how to expand the result of my i32
TargetGlobalAddress nodes. Adding my 32-bit register class in the
constructor, code is now generated for loading memory from these
addresses, but instructions are no longer selectable for the vast
majority of 16-bit data operations.

I have noticed that common to most of these selection errors is that
Constants are i32, they are copied to a virtual i32 register and a top
level operation (e.g. i32 xor) is where the fatal error is reported.
To check whether the constants are the source of the problem, I
changed ArchTargetLowering to custom lower i32 ISD::Constants,
replacing them with i16 equivalents (naive manual truncating of
values, suitable only for checking if constants are the problem, for
instance I can see soft floating point issues arising here). This made
some trivial examples disappear, but backend errors still appear and
of a similar form where an instruction can't be selected, one node is
a i32 CopyFromReg and where 32-bit registers have been chosen to store
things needlessly.

Has anyone had any experience with something similar, forcing LLVM to
not use a particular size register for anything other than for storing
addresses for loading/storing that might have ideas on how to solve
the issues I'm seeing?

Many Thanks,