Index: lib/Target/AMDGPU/SIDefines.h =================================================================== --- lib/Target/AMDGPU/SIDefines.h +++ lib/Target/AMDGPU/SIDefines.h @@ -126,7 +126,10 @@ /// Operand with 32-bit immediate that uses the constant bus. OPERAND_KIMM32, - OPERAND_KIMM16 + OPERAND_KIMM16, + + // Output register operand with 16-bit output. + OPERAND_REG_DEF16 }; } Index: lib/Target/AMDGPU/SIInstrFormats.td =================================================================== --- lib/Target/AMDGPU/SIInstrFormats.td +++ lib/Target/AMDGPU/SIInstrFormats.td @@ -187,6 +187,22 @@ } class VOPDstOperand : RegisterOperand ; +class VOP3DstOperand : RegisterOperand ; + +let OperandNamespace = "AMDGPU" in { +def VOPDstOperand16 : VOPDstOperand { + let OperandType = "OPERAND_REG_DEF16"; +} + +def VOP3DstOperand16 : VOP3DstOperand { + let OperandType = "OPERAND_REG_DEF16"; +} + +} + +def VOPDstOperand32 : VOPDstOperand; +def VOPDstOperand64 : VOPDstOperand; +def VOPDstOperand128 : VOPDstOperand; class VINTRPe op> : Enc32 { bits<8> vdst; Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -4540,7 +4540,21 @@ KnownZero = 0xffff0000; return; } - default: + default: { + // XXX - Are there any 16-bit output instructions with second defs? + // FIXME: + assert(Def->getOperand(0).getReg() == Op.getReg() && + Def->getOperand(0).getSubReg() == Op.getSubReg()); + if (Def->getDesc().OpInfo[0].OperandType == AMDGPU::OPERAND_REG_DEF16) { + // FIXME: This isn't true for all instructions on gfx9, where some new + // instructions default to leaving high bits intact and there is a control + // bit for old instructions to change zeroing behavior. + + KnownZero = 0xffff0000; + return; + } + return; + } } } Index: lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.td +++ lib/Target/AMDGPU/SIInstrInfo.td @@ -886,10 +886,19 @@ RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand, !if(!eq(VT.Size, 128), VOPDstOperand, !if(!eq(VT.Size, 64), VOPDstOperand, - !if(!eq(VT.Size, 16), VOPDstOperand, + !if(!eq(VT.Size, 16), VOPDstOperand16, VOPDstOperand)))); // else VT == i1 } +// Hack to avoid printing _e64 for instructions that must be VOP3. +class getVALUDstForVT_VOP3 { + RegisterOperand ret = !if(!eq(VT.Size, 32), VOP3DstOperand, + !if(!eq(VT.Size, 128), VOP3DstOperand, + !if(!eq(VT.Size, 64), VOP3DstOperand, + !if(!eq(VT.Size, 16), VOP3DstOperand16, + VOP3DstOperand)))); // else VT == i1 +} + // Returns the register class to use for the destination of VOP[12C] // instructions with SDWA extension class getSDWADstForVT { Index: lib/Target/AMDGPU/VOP3Instructions.td =================================================================== --- lib/Target/AMDGPU/VOP3Instructions.td +++ lib/Target/AMDGPU/VOP3Instructions.td @@ -121,10 +121,13 @@ // only VOP instruction that implicitly reads VCC. let Asm64 = " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod" in { def VOP_F32_F32_F32_F32_VCC : VOPProfile<[f32, f32, f32, f32]> { - let Outs64 = (outs DstRC.RegClass:$vdst); + // FIXME: Hack to stop printing _e64 + let DstRC = getVALUDstForVT_VOP3.ret; } + def VOP_F64_F64_F64_F64_VCC : VOPProfile<[f64, f64, f64, f64]> { - let Outs64 = (outs DstRC.RegClass:$vdst); + // FIXME: Hack to stop printing _e64 + let DstRC = getVALUDstForVT_VOP3.ret; } } @@ -139,7 +142,7 @@ class VOP3_Profile : VOPProfile { // FIXME: Hack to stop printing _e64 - let Outs64 = (outs DstRC.RegClass:$vdst); + let DstRC = getVALUDstForVT_VOP3.ret; let Asm64 = " " # P.Asm64; } @@ -158,17 +161,17 @@ def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile { // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; + let DstRC = getVALUDstForVT_VOP3.ret; } def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile { // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; + let DstRC = getVALUDstForVT_VOP3.ret; } def VOP3b_I64_I1_I32_I32_I64 : VOPProfile<[i64, i32, i32, i64]> { // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; + let DstRC = getVALUDstForVT_VOP3.ret; let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); let Asm64 = " $vdst, $sdst, $src0, $src1, $src2";