Promoting i16 load to i32

Hi,

I'm working on an LLVM backend for an architecture which does not
natively support half-word loads. I'm having trouble getting LLVM to
promote i16 to i32 loads for me - should I expect LLVM to be able to
do this, are do I have to write a custom lowerer? This post
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-February/019929.html)
gave me the impression that it should be possible, but maybe I
misinterpreted. Below is what I've tried (on an LLVM last synced with
upstream ~3 weeks ago).

I've set my target to promote i16 loads in its TargetLowering.
  setLoadExtAction(ISD::EXTLOAD, MVT::i16, Promote);
  setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Promote);
  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Promote);

The DataLayout is "e-p:32:32:32-i8:8:8-i16:32:32-i32:32:32-n32"

If I test with a simple function as the following (which adds two i16
arguments):

define zeroext i16 @a(i16 zeroext %x, i16 zeroext %y) nounwind {
entry:
  %x.addr = alloca i16, align 2
  %y.addr = alloca i16, align 2
  store i16 %x, i16* %x.addr, align 2
  store i16 %y, i16* %y.addr, align 2
  %tmp = load i16* %x.addr, align 2
  %conv = zext i16 %tmp to i32
  %tmp1 = load i16* %y.addr, align 2
  %conv2 = zext i16 %tmp1 to i32
  %add = add nsw i32 %conv, %conv2
  %conv3 = trunc i32 %add to i16
  ret i16 %conv3
}

Upon compiling I get this failed assertion:
llc: LegalizeDAG.cpp:1309:
llvm::SDValue<unnamed>::SelectionDAGLegalize::LegalizeOp(llvm::SDValue):
Assertion `0 && "This action is not supported yet!"' failed.

I initially expected the if statement on line 1191 (in my copy), `if
(SrcWidth != SrcVT.getStoreSizeInBits()` to catch my i16 promotion
case - but it doesn't because SrcVT.getSizeInBits() and
SrcVT.getStoreSizeInBits() equals 16 with SrcVT == MVT::i16.

I'd appreciate any pointers in the right direction.

Thank you,

Alex

Alex Bradbury wrote:

Hi,

I'm working on an LLVM backend for an architecture which does not
natively support half-word loads. I'm having trouble getting LLVM to
promote i16 to i32 loads for me - should I expect LLVM to be able to
do this, are do I have to write a custom lowerer?

I don't think LLVM does that currently. However - it would be a nice
thing have. At least spu and, if I recall correctly, xcore backends have
custom lowering for similar cases.

kalle

Hi Alex,

I'm working on an LLVM backend for an architecture which does not
natively support half-word loads. I'm having trouble getting LLVM to
promote i16 to i32 loads for me - should I expect LLVM to be able to
do this, are do I have to write a custom lowerer?

it should do this if i16 is not a legal type but i32 is.

Ciao, Duncan.