[llvm] [SPIR-V] Add OpSMulExtended and OpUMulExtended builtin support (PR #187474)
Dmitry Sidorov via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 27 09:05:04 PDT 2026
================
@@ -1996,6 +1996,97 @@ static bool generateICarryBorrowInst(const SPIRV::IncomingCall *Call,
return true;
}
+// We expect a builtin in one of two forms:
+//
+// (1) sret convention (3 arguments):
+// void Name(ptr sret([RetType]) %result, Type %operand1, Type %operand2)
+// => Res = Opcode RetType Operand1 Operand2
+// OpStore %result Res
+//
+// (2) direct return convention (2 arguments):
+// RetType Name(Type %operand1, Type %operand2)
+// => Res = Opcode RetType Operand1 Operand2
+//
+// RetType is a struct with two members of the same type as the operands.
+static bool generateMulExtendedInst(const SPIRV::IncomingCall *Call,
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry *GR) {
+ const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+ unsigned Opcode =
+ SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
+ assert((Opcode == SPIRV::OpUMulExtended || Opcode == SPIRV::OpSMulExtended) &&
+ "Expected OpUMulExtended or OpSMulExtended");
+
+ const bool IsSret =
+ !Call->ReturnType || Call->ReturnType->getOpcode() == SPIRV::OpTypeVoid;
+ Register Op1Reg = IsSret ? Call->Arguments[1] : Call->Arguments[0];
+ Register Op2Reg = IsSret ? Call->Arguments[2] : Call->Arguments[1];
+
+ SPIRVTypeInst RetType;
+ if (IsSret) {
+ Register SRetReg = Call->Arguments[0];
+ SPIRVTypeInst PtrRetType = GR->getSPIRVTypeForVReg(SRetReg);
+ RetType = GR->getPointeeType(PtrRetType);
+ if (!RetType)
+ report_fatal_error("The first parameter must be a pointer");
+ } else {
+ RetType = Call->ReturnType;
+ }
+
+ if (!RetType || RetType->getOpcode() != SPIRV::OpTypeStruct)
----------------
MrSidims wrote:
(since it's confuses me) default initialization for `SPIRVTypeInst` is nullptr, right?
https://github.com/llvm/llvm-project/pull/187474
More information about the llvm-commits
mailing list