[LLVMbugs] [Bug 4361] New: DAGCombine incorrectly generates 64bit ext load from 16 bit load on a platform with 32bit aligned addresses

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Wed Jun 10 12:39:26 PDT 2009


           Summary: DAGCombine incorrectly generates 64bit ext load from 16
                    bit load on a platform with 32bit aligned addresses
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: Windows NT
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Common Code Generator Code
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: micah.villmow at amd.com
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=3076)
 --> (http://llvm.org/bugs/attachment.cgi?id=3076)
incorrect extension of 16bit into 64bit

The following test case is a conversion routine from a ushort to a ulong:
define void @test_convert_ulong_ushort_kernel(i16 addrspace(1)* %src, i64
addrspace(1)* %dest) nounwind {
        %call = tail call i32 @get_global_id(i32 0) nounwind            ; <i32>
        %tmp2 = load i16 addrspace(1)* %src             ; <i16> [#uses=1]
        %conv.i.i = zext i16 %tmp2 to i64               ; <i64> [#uses=1]
        store i64 %conv.i.i, i64 addrspace(1)* %dest
        ret void

declare i32 @get_global_id(i32)

However, in DAGCombiner.cpp:visitSIGN_EXTEND:3054 and
DAGCombiner.cpp:visitZERO_EXTEND:3148, an incorrect conversion occurs as shown
in incorrectsext.dot which will be attached later. The problem is that it is
converting the 16bit load and an extension to 64bit to a 64bit sign extended
load followed by an and of the lower 16 bits. This works fine if the address
that the 16bit load is from is aligned to the 32bit boundary but does not work
if aligned to the 16bit boundary. 

If I comment out the blocks that contain this conversion:
// fold (sext (sextload x)) -> (sext (truncate (sextload x)))
  // fold (sext ( extload x)) -> (sext (truncate (sextload x)))

// fold (zext (load x)) -> (zext (truncate (zextload x)))

then the code gets generated as expected, a 16bit load followed by a zext as
specified in correctsext.dot.

I set all sextload/zextload's to expand via 
setLoadExtAction(ISD::SEXTLOAD, VT, Expand);        
setLoadExtAction(ISD::ZEXTLOAD, VT, Expand);

Where VT is all the value types that I support.
I also set
allowUnalignedMemoryAccesses = false;

The above bitcode given linear values 0-> (N-1) as input to short produces 0,
0, 2, 2, 4, 4, etc... as the second 16bit value does not get correctly shifted
into position.

With my backend, all 8/16 bit loads/stores MUST NOT be removed/combined as I
have custom assembly written that correctly handles the unaligned cases.

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list