[llvm] [AMDGPU] Add gfx1251 V_PK_ADD/SUB_NC_U64 (PR #203607)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 11:49:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Stanislav Mekhanoshin (rampitec)
<details>
<summary>Changes</summary>
---
Patch is 104.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203607.diff
19 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPU.td (+5)
- (modified) llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp (+10-1)
- (modified) llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp (+7-1)
- (modified) llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (+12-1)
- (modified) llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp (+2)
- (modified) llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (+1)
- (modified) llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp (+1)
- (modified) llvm/lib/Target/AMDGPU/SIDefines.h (+1)
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+15-1)
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.cpp (+5-1)
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.td (+1)
- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.td (+1)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (+4)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h (+1)
- (modified) llvm/lib/Target/AMDGPU/VOP3PInstructions.td (+16-1)
- (added) llvm/test/CodeGen/AMDGPU/packed-u64.ll (+1313)
- (modified) llvm/test/MC/AMDGPU/gfx1251_asm_vop3p.s (+96)
- (modified) llvm/test/MC/AMDGPU/gfx1251_err.s (+58)
- (modified) llvm/test/MC/Disassembler/AMDGPU/gfx1251_dasm_vop3p.txt (+72)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index b91091e97ca9d..5884b9edf57c9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -701,6 +701,10 @@ defm PackedFP64Ops : AMDGPUSubtargetFeature<"packed-fp64-ops",
"Support packed fp64 instructions"
>;
+defm PackedU64Ops : AMDGPUSubtargetFeature<"packed-u64-ops",
+ "Support packed uint64 instructions"
+>;
+
defm R128A16 : AMDGPUSubtargetFeature<"r128-a16",
"Support gfx9-style A16 for 16-bit coordinates/gradients/lod/clamp/mip image "
"operands, where a16 is aliased with r128"
@@ -2228,6 +2232,7 @@ def FeatureISAVersion12_51 : FeatureSet<
FeatureVOP3PX2IncrementsVaVdstTwice,
FeatureDPALU_DPP,
FeaturePackedFP64Ops,
+ FeaturePackedU64Ops,
FeatureGFX1251GEMMInsts,
FeatureGFX125xLowestRateWMMA,
FeatureCubeInsts,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 0ad3fbe9400ad..3c8f81ea5b11e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -760,7 +760,16 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
if (ST.hasVOP3PInsts() && ST.hasAddNoCarryInsts() && ST.hasIntClamp()) {
// Full set of gfx9 features.
- if (ST.hasScalarAddSub64()) {
+ if (ST.hasPackedU64Ops()) {
+ getActionDefinitionsBuilder({G_ADD, G_SUB})
+ .legalFor({S64, S32, S16, V2S16, V2S64})
+ .clampMaxNumElementsStrict(0, S16, 2)
+ .clampMaxNumElementsStrict(0, S64, 2)
+ .scalarize(0)
+ .minScalar(0, S16)
+ .widenScalarToNextMultipleOf(0, 32)
+ .maxScalar(0, S32);
+ } else if (ST.hasScalarAddSub64()) {
getActionDefinitionsBuilder({G_ADD, G_SUB})
.legalFor({S64, S32, S16, V2S16})
.clampMaxNumElementsStrict(0, S16, 2)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
index db8fc149df1f6..200234c23c886 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp
@@ -4063,8 +4063,14 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case AMDGPU::G_UBFX:
case AMDGPU::G_AMDGPU_S_MUL_I64_I32:
case AMDGPU::G_AMDGPU_S_MUL_U64_U32:
- if (isSALUMapping(MI))
+ if (isSALUMapping(MI)) {
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ unsigned Size = Ty.getSizeInBits();
+ // Packed add and sub are VALU only.
+ if (Subtarget.hasPackedU64Ops() && Ty.isVector() && Size == 128)
+ return getDefaultMappingVOP(MI);
return getDefaultMappingSOP(MI);
+ }
return getDefaultMappingVOP(MI);
case AMDGPU::G_SMIN:
case AMDGPU::G_SMAX:
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 21214e9e25162..175ea9911b2e2 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -617,6 +617,11 @@ class AMDGPUOperand : public MCParsedAsmOperand {
bool isVSrc_b64() const { return isVCSrc_f64() || isLiteralImm(MVT::i64); }
+ bool isVSrc_v2b64() const {
+ return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::i64) ||
+ isLiteralImm(MVT::i64);
+ }
+
bool isVSrc_v2f64() const {
return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::f64) ||
isLiteralImm(MVT::f64);
@@ -2086,6 +2091,7 @@ static const fltSemantics *getOpFltSemantics(uint8_t OperandType) {
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
case AMDGPU::OPERAND_KIMM64:
return &APFloat::IEEEdouble();
case AMDGPU::OPERAND_REG_IMM_FP16:
@@ -2407,6 +2413,7 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
if (Lit == LitModifier::None &&
AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
AsmParser->hasInv2PiInlineImm())) {
@@ -2540,6 +2547,7 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
if (Lit == LitModifier::None &&
AMDGPU::isInlinableLiteral64(Val, AsmParser->hasInv2PiInlineImm())) {
Inst.addOperand(MCOperand::createImm(Val));
@@ -5187,7 +5195,10 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,
Desc.operands()[OpIdx].OperandType == AMDGPU::OPERAND_KIMM64 ||
(Desc.operands()[OpIdx].OperandType == AMDGPU::OPERAND_REG_IMM_FP64 &&
HasMandatoryLiteral);
- bool IsFP64 = (IsForcedFP64 || AMDGPU::isSISrcFPOperand(Desc, OpIdx)) &&
+ unsigned OpTy = Desc.operands()[OpIdx].OperandType;
+ bool IsFP64 = (IsForcedFP64 ||
+ (AMDGPU::isSISrcFPOperand(Desc, OpIdx) &&
+ OpTy != AMDGPU::OPERAND_REG_IMM_V2INT64)) &&
AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
bool IsValid32Op =
IsForcedLit || AMDGPU::isValid32BitLiteral(Value, IsFP64);
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 44eee6d7c8af4..d57c06e689008 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -552,6 +552,7 @@ void AMDGPUDisassembler::decodeImmOperands(MCInst &MI,
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
Imm = getInlineImmVal64(Imm);
break;
default:
@@ -1687,6 +1688,7 @@ AMDGPUDisassembler::decodeLiteralConstant(const MCInstrDesc &Desc,
break;
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
UseLit = AMDGPU::isInlinableLiteral64(Val, HasInv2Pi);
break;
case MCOI::OPERAND_REGISTER:
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
index 866fb3f3e3788..f6d30f64e224e 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
@@ -873,6 +873,7 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
break;
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
printImmediate64(Op.getImm(), STI, O, false);
break;
case AMDGPU::OPERAND_REG_IMM_FP64:
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
index 69ec3baba9380..b3fdf38b9a688 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
@@ -314,6 +314,7 @@ std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
return getLit64Encoding(Desc, static_cast<uint64_t>(Imm), STI, false);
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h
index 2e9ca0783362a..6a5d82af41fb3 100644
--- a/llvm/lib/Target/AMDGPU/SIDefines.h
+++ b/llvm/lib/Target/AMDGPU/SIDefines.h
@@ -213,6 +213,7 @@ enum OperandType : unsigned {
OPERAND_REG_IMM_V2FP16,
OPERAND_REG_IMM_V2FP16_SPLAT,
OPERAND_REG_IMM_V2INT16,
+ OPERAND_REG_IMM_V2INT64,
OPERAND_REG_IMM_NOINLINE_V2FP16,
OPERAND_REG_IMM_V2INT32,
OPERAND_REG_IMM_V2FP32,
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index cf2c55cc360f8..f4f2f9e3632d8 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -918,6 +918,13 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
ISD::FMAXIMUMNUM, ISD::FCANONICALIZE},
{MVT::v4f64, MVT::v8f64, MVT::v16f64, MVT::v32f64}, Custom);
}
+
+ if (Subtarget->hasPackedU64Ops()) {
+ setOperationAction({ISD::ADD, ISD::SUB}, MVT::v2i64, Legal);
+ setOperationAction({ISD::ADD, ISD::SUB},
+ {MVT::v4i64, MVT::v8i64, MVT::v16i64, MVT::v32i64},
+ Custom);
+ }
}
setOperationAction({ISD::FNEG, ISD::FABS}, MVT::v4f16, Custom);
@@ -7492,7 +7499,14 @@ SDValue SITargetLowering::splitBinaryVectorOp(SDValue Op,
SelectionDAG &DAG) const {
unsigned Opc = Op.getOpcode();
EVT VT = Op.getValueType();
- assert(VT.isVector() && VT.getVectorElementCount().isKnownEven());
+ assert(VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16 ||
+ VT == MVT::v4f32 || VT == MVT::v8i16 || VT == MVT::v8f16 ||
+ VT == MVT::v8bf16 || VT == MVT::v16i16 || VT == MVT::v16f16 ||
+ VT == MVT::v16bf16 || VT == MVT::v8f32 || VT == MVT::v16f32 ||
+ VT == MVT::v32f32 || VT == MVT::v32i16 || VT == MVT::v32f16 ||
+ VT == MVT::v32bf16 || VT == MVT::v4f64 || VT == MVT::v8f64 ||
+ VT == MVT::v16f64 || VT == MVT::v32f64 || VT == MVT::v4i64 ||
+ VT == MVT::v8i64 || VT == MVT::v16i64 || VT == MVT::v32i64);
auto [Lo0, Hi0] = DAG.SplitVectorOperand(Op.getNode(), 0);
auto [Lo1, Hi1] = DAG.SplitVectorOperand(Op.getNode(), 1);
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index a5198cce50e0f..ba1f1b2effe9f 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -4823,6 +4823,7 @@ bool SIInstrInfo::isInlineConstant(int64_t Imm, uint8_t OperandType) const {
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
return AMDGPU::isInlinableLiteral64(Imm, ST.hasInv2PiInlineImm());
case AMDGPU::OPERAND_REG_IMM_INT16:
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
@@ -5313,6 +5314,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
case AMDGPU::OPERAND_REG_IMM_V2INT16:
case AMDGPU::OPERAND_REG_IMM_V2BF16:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
break;
case AMDGPU::OPERAND_REG_IMM_NOINLINE_V2FP16:
break;
@@ -6651,7 +6653,8 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
bool Is64BitOp = Is64BitFPOp ||
OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_INT64 ||
OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2INT32 ||
- OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2FP32;
+ OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2FP32 ||
+ OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2INT64;
if (Is64BitOp &&
!AMDGPU::isInlinableLiteral64(Imm, ST.hasInv2PiInlineImm())) {
if (!AMDGPU::isValid32BitLiteral(Imm, Is64BitFPOp) &&
@@ -10026,6 +10029,7 @@ unsigned SIInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
LiteralSize = 8;
break;
case AMDGPU::OPERAND_REG_IMM_INT64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
// A 32-bit literal is only valid when the value fits in BOTH signed
// and unsigned 32-bit ranges [0, 2^31-1], matching the MC code
// emitter's getLit64Encoding logic. This is because of the lack of
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td
index dd159354c421a..b3fffba0bd1a3 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td
@@ -3185,6 +3185,7 @@ def VOP_V16F32_V4I16_V4I16_V16F32 : VOPProfile <[v16f32, v4i16, v4i16, v16f32]>;
def VOP_V32F32_V4I16_V4I16_V32F32 : VOPProfile <[v32f32, v4i16, v4i16, v32f32]>;
def VOP_V2F64_V2F64_V2F64 : VOPProfile <[v2f64, v2f64, v2f64, untyped]>;
def VOP_V2F64_V2F64_V2F64_V2F64 : VOPProfile <[v2f64, v2f64, v2f64, v2f64]>;
+def VOP_V2I64_V2I64_V2I64 : VOPProfile <[v2i64, v2i64, v2i64, untyped]>;
def VOP_V4I32_I64_I64_V4I32 : VOPProfile <[v4i32, i64, i64, v4i32]>;
def VOP_V16I32_I64_I64_V16I32 : VOPProfile <[v16i32, i64, i64, v16i32]>;
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
index 75ac25c1c22d7..31f927709e682 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
@@ -1445,6 +1445,7 @@ def VSrc_f64 : SrcRegOrImm9 <VS_64_AlignTarget, "OPERAND_REG_IMM_FP64"> {
}
def VSrc_v2b32 : SrcRegOrImm9 <VS_64_AlignTarget, "OPERAND_REG_IMM_V2INT32">;
def VSrc_v2f32 : SrcRegOrImm9 <VS_64_AlignTarget, "OPERAND_REG_IMM_V2FP32">;
+def VSrc_v2b64 : SrcRegOrImm9 <VS_128, "OPERAND_REG_IMM_V2INT64">;
def VSrc_v2f64 : SrcRegOrImm9 <VS_128, "OPERAND_REG_IMM_V2FP64">;
def VSrc_NoInline_v2f16 : SrcRegOrImm9 <VS_32, "OPERAND_REG_IMM_NOINLINE_V2FP16">;
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 7c515172791e3..c1e9bc6336eb6 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -3853,6 +3853,10 @@ bool isPacked64BitInst(unsigned Opc) {
case AMDGPU::V_PK_MAX_NUM_F64_gfx1250:
case AMDGPU::V_PK_MIN_NUM_F64:
case AMDGPU::V_PK_MIN_NUM_F64_gfx1250:
+ case AMDGPU::V_PK_ADD_NC_U64:
+ case AMDGPU::V_PK_ADD_NC_U64_gfx1250:
+ case AMDGPU::V_PK_SUB_NC_U64:
+ case AMDGPU::V_PK_SUB_NC_U64_gfx1250:
return true;
default:
return false;
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 4b754fa6e36b6..6f45f6482ca9a 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -1687,6 +1687,7 @@ inline unsigned getOperandSize(const MCOperandInfo &OpInfo) {
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_REG_IMM_V2FP64:
+ case AMDGPU::OPERAND_REG_IMM_V2INT64:
case AMDGPU::OPERAND_KIMM64:
return 8;
diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
index 7acd2a08a3886..d6eb02d9c9c36 100644
--- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td
@@ -142,6 +142,12 @@ def V_PK_VOP3_F64_Profile : VOP3P_Profile<VOP_V2F64_V2F64_V2F64_V2F64, VOP3_PACK
let Src2RC64 = VSrc_v2f64;
}
+def V_PK_VOP2_I64_Profile : VOP3P_Profile<VOP_V2I64_V2I64_V2I64, VOP3_PACKED> {
+ let HasOpSel = 0;
+ let Src0RC64 = VSrc_v2b64;
+ let Src1RC64 = VSrc_v2b64;
+}
+
let isReMaterializable = 1 in {
let isCommutable = 1 in {
defm V_PK_MAD_I16 : VOP3PInst<"v_pk_mad_i16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16_V2I16>>;
@@ -169,11 +175,14 @@ defm V_PK_MAX_NUM_F64 : VOP3PInst<"v_pk_max_num_f64", V_PK_VOP2_F64_Profile, fma
defm V_PK_MIN_NUM_F64 : VOP3PInst<"v_pk_min_num_f64", V_PK_VOP2_F64_Profile, fminnum_like>;
}
+let SubtargetPredicate = HasPackedU64Ops, SchedRW = [Write64Bit] in
+defm V_PK_ADD_NC_U64 : VOP3PInst<"v_pk_add_nc_u64", V_PK_VOP2_I64_Profile, add>;
+
let SubtargetPredicate = HasIEEEMinimumMaximumInsts, ReadsModeReg = 0 in {
defm V_PK_MAXIMUM_F16 : VOP3PInst<"v_pk_maximum_f16", VOP3P_Profile<VOP_V2F16_V2F16_V2F16, VOP3_PACKED>, fmaximum>;
defm V_PK_MINIMUM_F16 : VOP3PInst<"v_pk_minimum_f16", VOP3P_Profile<VOP_V2F16_V2F16_V2F16, VOP3_PACKED>, fminimum>;
} // End SubtargetPredicate = HasIEEEMinimumMaximumInsts, ReadsModeReg = 0
-}
+} // End isCommutable = 1
defm V_PK_SUB_U16 : VOP3PInst<"v_pk_sub_u16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16>>;
defm V_PK_SUB_I16 : VOP3PInst<"v_pk_sub_i16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16>, sub>;
@@ -181,6 +190,10 @@ defm V_PK_SUB_I16 : VOP3PInst<"v_pk_sub_i16", VOP3P_Profile<VOP_V2I16_V2I16_V2I1
defm V_PK_LSHLREV_B16 : VOP3PInst<"v_pk_lshlrev_b16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16>, clshl_rev_16>;
defm V_PK_ASHRREV_I16 : VOP3PInst<"v_pk_ashrrev_i16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16>, cashr_rev_16>;
defm V_PK_LSHRREV_B16 : VOP3PInst<"v_pk_lshrrev_b16", VOP3P_Profile<VOP_V2I16_V2I16_V2I16>, clshr_rev_16>;
+
+let SubtargetPredicate = HasPackedU64Ops, SchedRW = [Write64Bit] in {
+defm V_PK_SUB_NC_U64 : VOP3PInst<"v_pk_sub_nc_u64", V_PK_VOP2_I64_Profile, sub>;
+} // End SubtargetPredicate = HasPackedU64Ops, , SchedRW = [Write64Bit]
} // End isReMaterializable = 1
let SubtargetPredicate = HasVOP3PInsts in {
@@ -2710,6 +2723,8 @@ let PostEncoderMethod = "postEncodeVOP3<true, true, false>" in {
defm V_PK_FMA_F64 : VOP3P_Real_gfx1250<0x3b>;
defm V_PK_MUL_F64 : VOP3P_Real_gfx1250<0x3c>;
defm V_PK_ADD_F64 : VOP3P_Real_gfx1250<0x4b>;
+defm V_PK_ADD_NC_U64 : VOP3P_Real_gfx1250<0x4c>;
+defm V_PK_SUB_NC_U64 : VOP3P_Real_gfx1250<0x4d>;
defm V_PK_MAX_NUM_F64 : VOP3P_Real_gfx1250<0x4e>;
defm V_PK_MIN_NUM_F64 : VOP3P_Real_gfx1250<0x4f>;
diff --git a/llvm/test/CodeGen/AMDGPU/packed-u64.ll b/llvm/test/CodeGen/AMDGPU/packed-u64.ll
new file mode 100644
index 0000000000000..f9efda624d52a
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/packed-u64.ll
@@ -0,0 +1,1313 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1251 < %s | FileCheck -enable-var-scope -check-prefixes=GFX1251,GFX1251-SDAG %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1251 < %s | FileCheck -enable-var-scope -check-prefixes=GFX1251,GFX1251-GISEL %s
+
+define amdgpu_kernel void @add_v2_vv(ptr addrspace(1) %a) {
+; GFX1251-LABEL: add_v2_vv:
+; GFX1251: ; %bb.0:
+; GFX1251-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1251-NEXT: s_load_b64 s[0:1], s[4:5], 0x24 nv
+; GFX1251-NEXT: v_and_b32_e32 v4, 0x3ff, v0
+; GFX1251-NEXT: s_wait_kmcnt 0x0
+; GFX1251-NEXT: global_load_b128 v[0:3], v4, s[0:1] scale_offset
+; GFX1251-NEXT: s_wait_loadcnt 0x0
+; GFX1251-NEXT: v_pk_add_nc_u64 v[0:3], v[0:3], v[0:3]
+; GFX1251-NEXT: global_store_b128 v4, v[0:3], s[0:1] scale_offset
+; GFX1251-NEXT: s_endpgm
+ %id = tail call i32 @llvm.amdgcn.workitem.id.x()
+ %gep = getelementptr inbounds <2 x i64>, ptr addrspace(1) %a, i32 %id
+ %load = load <2 x i64>, ptr addrspace(1) %gep, align 8
+ %add = add <2 x i64> %load, %load
+ store <2 x i64> %add, ptr addrspace(1) %gep, align 8
+ ret void
+}
+
+define amdgpu_kernel void @add_v2_vs(ptr addrspace(1) %a, <2 x i64> %x) {
+; GFX1251-LABEL: add_v2_vs:
+; GFX1251: ; %bb.0:
+; GFX1251-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1251-NEXT: s_clause 0x1
+; GFX1251-NEXT: s_load_b64 s[6:7], s[4:5], 0x24 nv
+; GFX1251-NEXT: s_load_b128 s[0:3], s[4:5], 0x34 nv
+; GFX1251-NEXT: v_and_b32_e32 v8, 0x3ff, v0
+; GFX1251-NEXT: s_wait_kmcnt 0x0
+; GFX1251-NEXT: global_load_b128 v[0:3], v8, s[6:7] scale_offset
+; GFX1251-NEXT: v_mov_b64_e32 v[6:7], s[2:3]
+; GFX1251-NEXT: v_mov_b64_e32 v[4:5], s[0:1]
+; GFX1251-NEXT: s_wait_loadcnt 0x0
+; GFX1251-NEXT: s_delay_alu instid0(VALU_DEP_1)
+; GFX1251-NEXT: v_pk_add_nc_u64 v[0:3], v[0:3], v[4:7]
+; GFX1251-NEXT: global_store_b128 v8, v[0:3], s[6:7] scale_offset
+; GFX1251-NEXT: s_endpgm
+ %id = tail call i32 @llvm.amdgcn.workitem.id.x()
+ %gep = getelementptr inbounds <2 x i64>, ptr addrspace(1) %a, i32 %id
+ %load = load <2 x i64>, ptr addrspace(1) %gep, align 8
+ %add = add <2 x i64> %load, %x
+ store <2 x i64> %add, ptr addrspace(1) %gep, align 8
+ ret void
+}
+
+define amdgpu_kernel void @add_v2_ss(ptr addrspace...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/203607
More information about the llvm-commits
mailing list