Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
unsigned IsBitwidth16 = MI->getFlags() & SPIRV::INST_PRINTER_WIDTH16;
const unsigned NumVarOps = MI->getNumOperands() - StartIndex;

if (MI->getOpcode() == SPIRV::OpConstantI && NumVarOps > 2) {
// SPV_ALTERA_arbitrary_precision_integers allows for integer widths greater
// than 64, which will be encoded via multiple operands.
for (unsigned I = StartIndex; I != MI->getNumOperands(); ++I)
O << ' ' << MI->getOperand(I).getImm();
return;
}

assert((NumVarOps == 1 || NumVarOps == 2) &&
"Unsupported number of bits for literal variable");

Expand Down
19 changes: 17 additions & 2 deletions llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@

#include "SPIRVCommandLine.h"
#include "MCTargetDesc/SPIRVBaseInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>

#include <functional>
#include <map>
#include <string>
#include <utility>
#include <vector>

#define DEBUG_TYPE "spirv-commandline"

Expand Down Expand Up @@ -176,7 +181,17 @@ bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
std::set<SPIRV::Extension::Extension> &Vals) {
SmallVector<StringRef, 10> Tokens;
ArgValue.split(Tokens, ",", -1, false);
std::sort(Tokens.begin(), Tokens.end());
llvm::sort(Tokens, [](auto &&LHS, auto &&RHS) {
// We want to ensure that we handle "all" first, to ensure that any
// subsequent disablement actually behaves as expected i.e. given
// --spv-ext=all,-foo, we first enable all and then disable foo; this should
// be revisited and simplified.
if (LHS == "all")
return true;
if (RHS == "all")
return false;
return !(RHS < LHS);
});

std::set<SPIRV::Extension::Extension> EnabledExtensions;

Expand Down
20 changes: 10 additions & 10 deletions llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,22 +151,22 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeBool(MachineIRBuilder &MIRBuilder) {
}

unsigned SPIRVGlobalRegistry::adjustOpTypeIntWidth(unsigned Width) const {
if (Width > 64)
report_fatal_error("Unsupported integer width!");
const SPIRVSubtarget &ST = cast<SPIRVSubtarget>(CurMF->getSubtarget());
if (ST.canUseExtension(
SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers) ||
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4))
(Width == 4 && ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)))
return Width;
if (Width <= 8)
Width = 8;
return 8;
else if (Width <= 16)
Width = 16;
return 16;
else if (Width <= 32)
Width = 32;
else
Width = 64;
return Width;
return 32;
else if (Width <= 64)
return 64;
else if (Width <= 128)
return 128;
reportFatalUsageError("Unsupported Integer width!");
}

SPIRVType *SPIRVGlobalRegistry::getOpTypeInt(unsigned Width,
Expand Down Expand Up @@ -413,7 +413,7 @@ Register SPIRVGlobalRegistry::createConstInt(const ConstantInt *CI,
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
addNumImm(APInt(BitWidth, CI->getZExtValue()), MIB);
addNumImm(CI->getValue(), MIB);
} else {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(Res)
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
const LLT s16 = LLT::scalar(16);
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
const LLT s128 = LLT::scalar(128);

const LLT v16s64 = LLT::fixed_vector(16, 64);
const LLT v16s32 = LLT::fixed_vector(16, 32);
Expand Down Expand Up @@ -307,7 +308,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
typeInSet(1, allPtrsScalarsAndVectors)));

getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE})
.legalFor({s1})
.legalFor({s1, s128})
.legalFor(allFloatAndIntScalarsAndPtrs)
.legalFor(allowedVectorTypes)
.moreElementsToNextPow2(0)
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,21 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::Int16);
else if (BitWidth == 8)
Reqs.addCapability(SPIRV::Capability::Int8);
else if (BitWidth == 4 &&
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_int4);
Reqs.addCapability(SPIRV::Capability::Int4TypeINTEL);
} else if (BitWidth != 32) {
if (!ST.canUseExtension(
SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
reportFatalUsageError(
"OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
"requires the following SPIR-V extension: "
"SPV_ALTERA_arbitrary_precision_integers");
Reqs.addExtension(
SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
Reqs.addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
}
break;
}
case SPIRV::OpDot: {
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB) {
// Asm Printer needs this info to print 64-bit operands correctly
MIB.getInstr()->setAsmPrinterFlag(SPIRV::ASM_PRINTER_WIDTH64);
return;
} else if (Bitwidth <= 128) {
uint32_t LowBits = Imm.getRawData()[0] & 0xffffffff;
uint32_t MidBits0 = (Imm.getRawData()[0] >> 32) & 0xffffffff;
uint32_t MidBits1 = Imm.getRawData()[1] & 0xffffffff;
uint32_t HighBits = (Imm.getRawData()[1] >> 32) & 0xffffffff;
MIB.addImm(LowBits).addImm(MidBits0).addImm(MidBits1).addImm(HighBits);
return;
}
report_fatal_error("Unsupported constant bitwidth");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR

; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - | FileCheck %s
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - -filetype=obj | spirv-val %}

; CHECK-ERROR: LLVM ERROR: OpTypeInt type with a width other than 8, 16, 32 or 64 bits requires the following SPIR-V extension: SPV_ALTERA_arbitrary_precision_integers

; CHECK: OpCapability ArbitraryPrecisionIntegersALTERA
; CHECK: OpExtension "SPV_ALTERA_arbitrary_precision_integers"
; CHECK: OpName %[[#TestAdd:]] "test_add"
; CHECK: OpName %[[#TestSub:]] "test_sub"
; CHECK: %[[#Int128Ty:]] = OpTypeInt 128 0
; CHECK: %[[#Const64Int128:]] = OpConstant %[[#Int128Ty]] 64 0 0 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious (potentially thinking about, what we might be missing): what happens with i126 scalars?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! Today it fails opaquely, with Unsupported integer width. With this patch it'd either pass if the required extension is present, or fail at module analysis with a slightly more informative message around needing to add the extension.


; CHECK: %[[#TestAdd]] = OpFunction
define spir_func void @test_add(i64 %AL, i64 %AH, i64 %BL, i64 %BH, ptr %RL, ptr %RH) {
entry:
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpShiftLeftLogical %[[#Int128Ty]] {{%[0-9]+}} %[[#Const64Int128]]
; CHECK: {{.*}} = OpBitwiseOr %[[#Int128Ty]]
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpIAdd %[[#Int128Ty]]
%tmp1 = zext i64 %AL to i128
%tmp23 = zext i64 %AH to i128
%tmp4 = shl i128 %tmp23, 64
%tmp5 = or i128 %tmp4, %tmp1
%tmp67 = zext i64 %BL to i128
%tmp89 = zext i64 %BH to i128
%tmp11 = shl i128 %tmp89, 64
%tmp12 = or i128 %tmp11, %tmp67
%tmp15 = add i128 %tmp12, %tmp5
%tmp1617 = trunc i128 %tmp15 to i64
store i64 %tmp1617, ptr %RL
%tmp21 = lshr i128 %tmp15, 64
%tmp2122 = trunc i128 %tmp21 to i64
store i64 %tmp2122, ptr %RH
ret void
; CHECK: OpFunctionEnd
}

; CHECK: %[[#TestSub]] = OpFunction
define spir_func void @test_sub(i64 %AL, i64 %AH, i64 %BL, i64 %BH, ptr %RL, ptr %RH) {
entry:
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpShiftLeftLogical %[[#Int128Ty]] {{%[0-9]+}} %[[#Const64Int128]]
; CHECK: {{.*}} = OpBitwiseOr %[[#Int128Ty]]
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpISub %[[#Int128Ty]]
%tmp1 = zext i64 %AL to i128
%tmp23 = zext i64 %AH to i128
%tmp4 = shl i128 %tmp23, 64
%tmp5 = or i128 %tmp4, %tmp1
%tmp67 = zext i64 %BL to i128
%tmp89 = zext i64 %BH to i128
%tmp11 = shl i128 %tmp89, 64
%tmp12 = or i128 %tmp11, %tmp67
%tmp15 = sub i128 %tmp5, %tmp12
%tmp1617 = trunc i128 %tmp15 to i64
store i64 %tmp1617, ptr %RL
%tmp21 = lshr i128 %tmp15, 64
%tmp2122 = trunc i128 %tmp21 to i64
store i64 %tmp2122, ptr %RH
ret void
; CHECK: OpFunctionEnd
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR

; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - | FileCheck %s
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - -filetype=obj | spirv-val %}

; CHECK-ERROR: LLVM ERROR: OpTypeInt type with a width other than 8, 16, 32 or 64 bits requires the following SPIR-V extension: SPV_ALTERA_arbitrary_precision_integers

; CHECK: OpCapability ArbitraryPrecisionIntegersALTERA
; CHECK: OpExtension "SPV_ALTERA_arbitrary_precision_integers"
; CHECK: OpName %[[#Foo:]] "foo"
; CHECK: %[[#Int128Ty:]] = OpTypeInt 128 0

; CHECK: %[[#Foo]] = OpFunction
define i64 @foo(i64 %x, i64 %y, i32 %amt) {
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpSConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpBitwiseOr %[[#Int128Ty]]
; CHECK: {{.*}} = OpUConvert %[[#Int128Ty]]
; CHECK: {{.*}} = OpShiftRightLogical %[[#Int128Ty]]
%tmp0 = zext i64 %x to i128
%tmp1 = sext i64 %y to i128
%tmp2 = or i128 %tmp0, %tmp1
%tmp7 = zext i32 13 to i128
%tmp3 = lshr i128 %tmp2, %tmp7
%tmp4 = trunc i128 %tmp3 to i64
ret i64 %tmp4
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR

; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - | FileCheck %s
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - -filetype=obj | spirv-val %}

; CHECK-ERROR: LLVM ERROR: OpTypeInt type with a width other than 8, 16, 32 or 64 bits requires the following SPIR-V extension: SPV_ALTERA_arbitrary_precision_integers

; CHECK: OpCapability ArbitraryPrecisionIntegersALTERA
; CHECK: OpExtension "SPV_ALTERA_arbitrary_precision_integers"
; CHECK: OpName %[[#Test:]] "test"
; CHECK: OpName %[[#Exit:]] "exit"
; CHECK: %[[#Int128Ty:]] = OpTypeInt 128 0
; CHECK: %[[#UndefInt128:]] = OpUndef %[[#Int128Ty]]

; CHECK: %[[#Test]] = OpFunction
define void @test() {
entry:
; CHECK: OpSwitch %[[#UndefInt128]] %[[#Exit]] 0 0 3 0 %[[#Exit]] 0 0 5 0 %[[#Exit]] 0 0 4 0 %[[#Exit]] 0 0 8 0 %[[#Exit]]
switch i128 poison, label %exit [
i128 55340232221128654848, label %exit
i128 92233720368547758080, label %exit
i128 73786976294838206464, label %exit
i128 147573952589676412928, label %exit
]
exit:
unreachable
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=all,-SPV_ALTERA_arbitrary_precision_integers %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=-SPV_ALTERA_arbitrary_precision_integers,all %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=KHR %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=khr %s -o - | FileCheck %s

Expand Down