16bit loads being promoted to 32bit?

I have the following function:

define void @test_fc_0_kernel(i16 signext %x, i16 signext %y, i16
addrspace(11)* %input, i32 addrspace(11)* %result) {

entry:

            %call = tail call i32 @get_id(i32 0) ;
<i32> [#uses=2]

            %cmp = icmp slt i16 %x, %y ; <i1> [#uses=1]

            br i1 %cmp, label %if.then, label %if.end

if.end: ; preds = %entry

            ret void

if.then: ; preds = %entry

            %arrayidx = getelementptr i32 addrspace(11)* %result, i32
%call ; <i32 addrspace(11)*> [#uses=1]

            %arrayidx7 = getelementptr i16 addrspace(11)* %input, i32
%call ; <i16 addrspace(11)*> [#uses=1]

            %tmp8 = load i16 addrspace(11)* %arrayidx7
; <i16> [#uses=1]

            %conv9 = sext i16 %tmp8 to i32 ; <i32> [#uses=1]

            store i32 %conv9, i32 addrspace(11)* %arrayidx

            ret void

}

This function should read from a memory location from input and write to
result with a promotion from i16 to i32, which seems simple enough. The
problem that I am having is somewhere along the line the 16bit load is
being promoted to a 32bit load and then the lower 16 bits are being sign
extended away with a shl 16 followed by a shr 16.

The problem with this is that

1) I'm limited to 32bit aligned loads and llvm is assuming a
16bit/8bit alignment

2) I have special functions that I need to be called when a load
of sub32bit data type occurs which handles the alignment constraints and
then does the shifting and masking of the data

So my questions are:

What bits do I need to flip to stop this optimization from occurring?

What do I need to set to correctly get the loads/stores generated if not
setting the datalayout string in my targetmachine class?

Thanks,

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

S1-609 One AMD Place

Sunnyvale, CA. 94085

P: 408-749-3966

The
problem that I am having is somewhere along the line the 16bit load is being
promoted to a 32bit load

For the given testcase, that's clearly illegal. Either there's a
serious bug in LLVM, or you're misinterpreting the meaning of the DAG.
Are you sure you aren't seeing a sign-extending load? If you don't
want to bother supporting extending loads, you can use
setLoadExtAction to make Legalize take care of it.

1) I'm limited to 32bit aligned loads and llvm is assuming a
16bit/8bit alignment

You shouldn't be seeing any unaligned loads post-Legalize unless you
explicitly ask for them by setting allowUnalignedMemoryAccesses to
true.

-Eli

Hi,

This function should read from a memory location from input and write to
result with a promotion from i16 to i32, which seems simple enough. The
problem that I am having is somewhere along the line the 16bit load is
being promoted to a 32bit load and then the lower 16 bits are being sign
extended away with a shl 16 followed by a shr 16.

most likely it is being turned into an i32 extending load (extended
from i16). You have to read the SDag node dumps carefully to notice
this. Being an extending load means that only 16 bits will actually
be loaded (only two bytes of memory touched), but the result will be
an i32. Hard to say anything more without details.

Ciao,

Duncan.

Eli,
Thanks that worked. :wink:

Micah