Index: lib/Target/R600/R600ISelLowering.cpp =================================================================== --- lib/Target/R600/R600ISelLowering.cpp +++ lib/Target/R600/R600ISelLowering.cpp @@ -1400,8 +1400,9 @@ for (unsigned i = 0, e = Ins.size(); i < e; ++i) { CCValAssign &VA = ArgLocs[i]; - EVT VT = Ins[i].VT; - EVT MemVT = LocalIns[i].VT; + const ISD::InputArg &In = Ins[i]; + EVT VT = In.VT; + EVT MemVT = In.VT; if (ShaderType != ShaderType::COMPUTE) { unsigned Reg = MF.addLiveIn(VA.getLocReg(), &AMDGPU::R600_Reg128RegClass); @@ -1423,11 +1424,20 @@ // FIXME: This should really check the extload type, but the handling of // extload vecto parameters seems to be broken. - //ISD::LoadExtType Ext = Ins[i].Flags.isSExt() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; + //ISD::LoadExtType Ext = In.Flags.isSExt() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; ISD::LoadExtType Ext = ISD::SEXTLOAD; + + // Compute the offset from the value. + // XXX - I think PartOffset should give you this, but it seems to give the + // size of the register which isn't useful. + + unsigned ValBase = ArgLocs[In.OrigArgIndex].getLocMemOffset(); + unsigned PartOffset = VA.getLocMemOffset(); + + MachinePointerInfo PtrInfo(UndefValue::get(PtrTy), PartOffset - ValBase); SDValue Arg = DAG.getExtLoad(Ext, DL, VT, Chain, - DAG.getConstant(36 + VA.getLocMemOffset(), MVT::i32), - MachinePointerInfo(UndefValue::get(PtrTy)), + DAG.getConstant(36 + PartOffset, MVT::i32), + PtrInfo, MemVT, false, false, 4); // 4 is the preferred alignment for the CONSTANT memory space. Index: test/CodeGen/R600/kernel-args.ll =================================================================== --- test/CodeGen/R600/kernel-args.ll +++ test/CodeGen/R600/kernel-args.ll @@ -453,3 +453,21 @@ store <16 x float> %in, <16 x float> addrspace(1)* %out, align 4 ret void } + +; FUNC-LABEL: @kernel_arg_i64 +; SI: S_LOAD_DWORDX2 +; SI: S_LOAD_DWORDX2 +; SI: BUFFER_STORE_DWORDX2 +define void @kernel_arg_i64(i64 addrspace(1)* %out, i64 %a) nounwind { + store i64 %a, i64 addrspace(1)* %out, align 8 + ret void +} + +; FUNC-LABEL: @kernel_arg_v1i64 +; SI: S_LOAD_DWORDX2 +; SI: S_LOAD_DWORDX2 +; SI: BUFFER_STORE_DWORDX2 +define void @kernel_arg_v1i64(<1 x i64> addrspace(1)* %out, <1 x i64> %a) nounwind { + store <1 x i64> %a, <1 x i64> addrspace(1)* %out, align 8 + ret void +} Index: test/CodeGen/R600/v1i64-kernel-arg.ll =================================================================== --- test/CodeGen/R600/v1i64-kernel-arg.ll +++ /dev/null @@ -1,17 +0,0 @@ -; REQUIRES: asserts -; XFAIL: * -; RUN: llc -march=r600 -mcpu=cypress < %s | FileCheck %s - -; CHECK-LABEL: @kernel_arg_i64 -define void @kernel_arg_i64(i64 addrspace(1)* %out, i64 %a) nounwind { - store i64 %a, i64 addrspace(1)* %out, align 8 - ret void -} - -; i64 arg works, v1i64 arg does not. -; CHECK-LABEL: @kernel_arg_v1i64 -define void @kernel_arg_v1i64(<1 x i64> addrspace(1)* %out, <1 x i64> %a) nounwind { - store <1 x i64> %a, <1 x i64> addrspace(1)* %out, align 8 - ret void -} -