Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -822,6 +822,7 @@ bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(SDValue Addr, SDValue &Base, SDValue &Offset) const { + SDLoc DL(Addr); if (CurDAG->isBaseWithConstantOffset(Addr)) { SDValue N0 = Addr.getOperand(0); SDValue N1 = Addr.getOperand(1); @@ -829,7 +830,7 @@ if (isDSOffsetLegal(N0, C1->getSExtValue(), 16)) { // (add n0, c0) Base = N0; - Offset = N1; + Offset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); return true; } } else if (Addr.getOpcode() == ISD::SUB) { @@ -837,7 +838,6 @@ if (const ConstantSDNode *C = dyn_cast(Addr.getOperand(0))) { int64_t ByteOffset = C->getSExtValue(); if (isUInt<16>(ByteOffset)) { - SDLoc DL(Addr); SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); // XXX - This is kind of hacky. Create a dummy sub node so we can check Index: llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.cpp +++ llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -224,10 +224,6 @@ // will use this for some partially aligned loads. const MachineOperand *Offset0Imm = getNamedOperand(*LdSt, AMDGPU::OpName::offset0); - // DS_PERMUTE does not have Offset0Imm (and Offset1Imm). - if (!Offset0Imm) - return false; - const MachineOperand *Offset1Imm = getNamedOperand(*LdSt, AMDGPU::OpName::offset1); Index: llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td +++ llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td @@ -2494,16 +2494,16 @@ multiclass DS_1A1D_PERMUTE op, string opName, RegisterClass rc, SDPatternOperator node = null_frag, dag outs = (outs rc:$vdst), - dag ins = (ins VGPR_32:$addr, rc:$data0), - string asm = opName#" $vdst, $addr, $data0"> { + dag ins = (ins VGPR_32:$addr, rc:$data0, offset:$offset), + string asm = opName#" $vdst, $addr, $data0"#"$offset"> { let mayLoad = 0, mayStore = 0, isConvergent = 1 in { def "" : DS_Pseudo ; + [(set i32:$vdst, + (node (DS1Addr1Offset i32:$addr, i16:$offset), i32:$data0))]>; - let data1 = 0, offset0 = 0, offset1 = 0, gds = 0 in { - def "_vi" : DS_Real_vi ; + let data1 = 0, gds = 0 in { + def "_vi" : DS_Off16_Real_vi ; } } } Index: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.bpermute.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.bpermute.ll +++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.bpermute.ll @@ -11,4 +11,14 @@ ret void } +; CHECK-LABEL: {{^}}ds_bpermute_imm_offset: +; CHECK: ds_bpermute_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:4 +; CHECK: s_waitcnt lgkmcnt +define void @ds_bpermute_imm_offset(i32 addrspace(1)* %out, i32 %base_index, i32 %src) nounwind { + %index = add i32 %base_index, 4 + %bpermute = call i32 @llvm.amdgcn.ds.bpermute(i32 %index, i32 %src) #0 + store i32 %bpermute, i32 addrspace(1)* %out, align 4 + ret void +} + attributes #0 = { nounwind readnone convergent } Index: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.permute.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.permute.ll +++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.ds.permute.ll @@ -2,7 +2,7 @@ declare i32 @llvm.amdgcn.ds.permute(i32, i32) #0 -; FUNC-LABEL: {{^}}ds_permute: +; CHECK-LABEL: {{^}}ds_permute: ; CHECK: ds_permute_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} ; CHECK: s_waitcnt lgkmcnt define void @ds_permute(i32 addrspace(1)* %out, i32 %index, i32 %src) nounwind { @@ -11,4 +11,14 @@ ret void } +; CHECK-LABEL: {{^}}ds_permute_imm_offset: +; CHECK: ds_permute_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:4 +; CHECK: s_waitcnt lgkmcnt +define void @ds_permute_imm_offset(i32 addrspace(1)* %out, i32 %base_index, i32 %src) nounwind { + %index = add i32 %base_index, 4 + %bpermute = call i32 @llvm.amdgcn.ds.permute(i32 %index, i32 %src) #0 + store i32 %bpermute, i32 addrspace(1)* %out, align 4 + ret void +} + attributes #0 = { nounwind readnone convergent }