[llvm] [SPIR-V]: Fix creation of constants of array types in SPIRV Backend (PR #96514)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 24 13:15:29 PDT 2024
https://github.com/VyacheslavLevytskyy updated https://github.com/llvm/llvm-project/pull/96514
>From 9576a1299cb418ff4875c760cd7125c82f6d9362 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 24 Jun 2024 09:28:28 -0700
Subject: [PATCH 1/5] fix creation of constants of array types
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 5 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 36 +++---------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 8 +--
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +-
llvm/test/CodeGen/SPIRV/var-uniform-const.ll | 55 +++++++++++++++++++
5 files changed, 72 insertions(+), 34 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/var-uniform-const.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index f5f36075d4a31..71168d2d7dacd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1972,7 +1972,10 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
.addDef(GlobalWorkSize)
.addUse(GR->getSPIRVTypeID(SpvFieldTy))
.addUse(GWSPtr);
- Const = GR->getOrCreateConsIntArray(0, MIRBuilder, SpvFieldTy);
+ const SPIRVSubtarget &ST =
+ cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
+ Const = GR->getOrCreateConstIntArray(0, Size, *MIRBuilder.getInsertPt(),
+ SpvFieldTy, *ST.getInstrInfo());
} else {
Const = GR->buildConstantInt(0, MIRBuilder, SpvTy);
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index b8710d24bff94..55b1b3684a393 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -394,7 +394,7 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
Constant *Val, MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII, Constant *CA, unsigned BitWidth,
unsigned ElemCnt, bool ZeroAsNull) {
- // Find a constant vector in DT or build a new one.
+ // Find a constant vector or array in DT or build a new one.
Register Res = DT.find(CA, CurMF);
// If no values are attached, the composite is null constant.
bool IsNull = Val->isNullValue() && ZeroAsNull;
@@ -474,20 +474,20 @@ Register SPIRVGlobalRegistry::getOrCreateConstVector(APFloat Val,
ZeroAsNull);
}
-Register
-SPIRVGlobalRegistry::getOrCreateConsIntArray(uint64_t Val, MachineInstr &I,
- SPIRVType *SpvType,
- const SPIRVInstrInfo &TII) {
+Register SPIRVGlobalRegistry::getOrCreateConstIntArray(
+ uint64_t Val, size_t Num, MachineInstr &I, SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII) {
const Type *LLVMTy = getTypeForSPIRVType(SpvType);
assert(LLVMTy->isArrayTy());
const ArrayType *LLVMArrTy = cast<ArrayType>(LLVMTy);
Type *LLVMBaseTy = LLVMArrTy->getElementType();
- auto *ConstInt = ConstantInt::get(LLVMBaseTy, Val);
- auto *ConstArr =
- ConstantArray::get(const_cast<ArrayType *>(LLVMArrTy), {ConstInt});
+ Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
+ SmallVector<Constant *> NumCI(Num, CI);
+ Constant *ConstArr =
+ ConstantArray::get(const_cast<ArrayType *>(LLVMArrTy), NumCI);
SPIRVType *SpvBaseTy = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
unsigned BW = getScalarOrVectorBitWidth(SpvBaseTy);
- return getOrCreateCompositeOrNull(ConstInt, I, SpvType, TII, ConstArr, BW,
+ return getOrCreateCompositeOrNull(CI, I, SpvType, TII, ConstArr, BW,
LLVMArrTy->getNumElements());
}
@@ -545,24 +545,6 @@ SPIRVGlobalRegistry::getOrCreateConsIntVector(uint64_t Val,
SpvType->getOperand(2).getImm());
}
-Register
-SPIRVGlobalRegistry::getOrCreateConsIntArray(uint64_t Val,
- MachineIRBuilder &MIRBuilder,
- SPIRVType *SpvType, bool EmitIR) {
- const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- assert(LLVMTy->isArrayTy());
- const ArrayType *LLVMArrTy = cast<ArrayType>(LLVMTy);
- Type *LLVMBaseTy = LLVMArrTy->getElementType();
- const auto ConstInt = ConstantInt::get(LLVMBaseTy, Val);
- auto ConstArr =
- ConstantArray::get(const_cast<ArrayType *>(LLVMArrTy), {ConstInt});
- SPIRVType *SpvBaseTy = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
- unsigned BW = getScalarOrVectorBitWidth(SpvBaseTy);
- return getOrCreateIntCompositeOrNull(Val, MIRBuilder, SpvType, EmitIR,
- ConstArr, BW,
- LLVMArrTy->getNumElements());
-}
-
Register
SPIRVGlobalRegistry::getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 990d3328f6a30..a45e1ccd0717f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -457,13 +457,11 @@ class SPIRVGlobalRegistry {
Register getOrCreateConstVector(APFloat Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
- Register getOrCreateConsIntArray(uint64_t Val, MachineInstr &I,
- SPIRVType *SpvType,
- const SPIRVInstrInfo &TII);
+ Register getOrCreateConstIntArray(uint64_t Val, size_t Num, MachineInstr &I,
+ SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII);
Register getOrCreateConsIntVector(uint64_t Val, MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType, bool EmitIR = true);
- Register getOrCreateConsIntArray(uint64_t Val, MachineIRBuilder &MIRBuilder,
- SPIRVType *SpvType, bool EmitIR = true);
Register getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType);
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 41a0d2c5e2f35..f5b6bcd64f480 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -846,7 +846,7 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
unsigned Num = getIConstVal(I.getOperand(2).getReg(), MRI);
SPIRVType *ValTy = GR.getOrCreateSPIRVIntegerType(8, I, TII);
SPIRVType *ArrTy = GR.getOrCreateSPIRVArrayType(ValTy, Num, I, TII);
- Register Const = GR.getOrCreateConsIntArray(Val, I, ArrTy, TII);
+ Register Const = GR.getOrCreateConstIntArray(Val, Num, I, ArrTy, TII);
SPIRVType *VarTy = GR.getOrCreateSPIRVPointerType(
ArrTy, I, TII, SPIRV::StorageClass::UniformConstant);
// TODO: check if we have such GV, add init, use buildGlobalVariable.
diff --git a/llvm/test/CodeGen/SPIRV/var-uniform-const.ll b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
new file mode 100644
index 0000000000000..da02b444e1f4a
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
@@ -0,0 +1,55 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; TODO: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-SPIRV-DAG: %[[#Char:]] = OpTypeInt 8 0
+; CHECK-SPIRV-DAG: %[[#Long:]] = OpTypeInt 64 0
+; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-SPIRV-DAG: %[[#Size3:]] = OpConstant %[[#Int]] 3
+; CHECK-SPIRV-DAG: %[[#Arr3:]] = OpTypeArray %[[#Char]] %[[#Size3]]
+; CHECK-SPIRV-DAG: %[[#Size16:]] = OpConstant %[[#Int]] 16
+; CHECK-SPIRV-DAG: %[[#Arr16:]] = OpTypeArray %[[#Char]] %[[#Size16]]
+; CHECK-SPIRV-DAG: %[[#Const3:]] = OpConstant %[[#Long]] 3
+; CHECK-SPIRV-DAG: %[[#One:]] = OpConstant %[[#Char]] 1
+; CHECK-SPIRV-DAG: %[[#One3:]] = OpConstantComposite %[[#Arr3]] %[[#One]] %[[#One]] %[[#One]]
+; CHECK-SPIRV-DAG: %[[#Zero3:]] = OpConstantNull %[[#Arr3]]
+; CHECK-SPIRV-DAG: %[[#Const16:]] = OpConstant %[[#Long]] 16
+; CHECK-SPIRV-DAG: %[[#One16:]] = OpConstantComposite %[[#Arr16]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]]
+; CHECK-SPIRV-DAG: %[[#Zero16:]] = OpConstantNull %[[#Arr16]]
+; CHECK-SPIRV-DAG: %[[#PtrArr3:]] = OpTypePointer UniformConstant %[[#Arr3]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#One3]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#Zero3]]
+; CHECK-SPIRV-DAG: %[[#PtrArr16:]] = OpTypePointer UniformConstant %[[#Arr16]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#One16]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#Zero16]]
+; CHECK-SPIRV: OpFunction
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
+; CHECK-SPIRV: OpFunctionEnd
+; CHECK-SPIRV: OpFunction
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
+; CHECK-SPIRV: OpFunctionEnd
+
+%Vec3 = type { <3 x i8> }
+%Vec16 = type { <16 x i8> }
+
+define spir_kernel void @foo(ptr addrspace(1) noundef align 16 %arg) {
+ %a1 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 3, i1 false)
+ %a2 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a2, i8 1, i64 3, i1 false)
+ ret void
+}
+
+define spir_kernel void @bar(ptr addrspace(1) noundef align 16 %arg) {
+ %a1 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 16, i1 false)
+ %a2 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a2, i8 1, i64 16, i1 false)
+ ret void
+}
+
+declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture writeonly, i8, i64, i1 immarg)
>From 1c60e5430081d2a8cd1cd6a920d83b1361bd1f95 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 24 Jun 2024 10:23:32 -0700
Subject: [PATCH 2/5] change an approach to creating a unique key
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 55b1b3684a393..245bc761c6f69 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -482,12 +482,20 @@ Register SPIRVGlobalRegistry::getOrCreateConstIntArray(
const ArrayType *LLVMArrTy = cast<ArrayType>(LLVMTy);
Type *LLVMBaseTy = LLVMArrTy->getElementType();
Constant *CI = ConstantInt::get(LLVMBaseTy, Val);
- SmallVector<Constant *> NumCI(Num, CI);
- Constant *ConstArr =
- ConstantArray::get(const_cast<ArrayType *>(LLVMArrTy), NumCI);
SPIRVType *SpvBaseTy = getSPIRVTypeForVReg(SpvType->getOperand(1).getReg());
unsigned BW = getScalarOrVectorBitWidth(SpvBaseTy);
- return getOrCreateCompositeOrNull(CI, I, SpvType, TII, ConstArr, BW,
+ // The following is reasonably unique key that is better that [Val]. The naive
+ // alternative would be something along the lines of:
+ // SmallVector<Constant *> NumCI(Num, CI);
+ // Constant *UniqueKey =
+ // ConstantArray::get(const_cast<ArrayType*>(LLVMArrTy), NumCI);
+ // that would be a truly unique but dangerous key, because it could lead to
+ // creation of constant of arbitrary length (that is the parameter of memset)
+ // which were missing in an original module.
+ Constant *UniqueKey = ConstantStruct::getAnon(
+ {PoisonValue::get(const_cast<ArrayType *>(LLVMArrTy)),
+ ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(LLVMBaseTy, Num)});
+ return getOrCreateCompositeOrNull(CI, I, SpvType, TII, UniqueKey, BW,
LLVMArrTy->getNumElements());
}
>From 11776e4bf08a7be3725d5144dc860688fc71a5e9 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 24 Jun 2024 12:23:36 -0700
Subject: [PATCH 3/5] harden the test case
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 10 ++---
llvm/test/CodeGen/SPIRV/var-uniform-const.ll | 42 ++++++++++++++++---
2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 245bc761c6f69..5558c7a5a4a5f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -486,12 +486,12 @@ Register SPIRVGlobalRegistry::getOrCreateConstIntArray(
unsigned BW = getScalarOrVectorBitWidth(SpvBaseTy);
// The following is reasonably unique key that is better that [Val]. The naive
// alternative would be something along the lines of:
- // SmallVector<Constant *> NumCI(Num, CI);
- // Constant *UniqueKey =
- // ConstantArray::get(const_cast<ArrayType*>(LLVMArrTy), NumCI);
+ // SmallVector<Constant *> NumCI(Num, CI);
+ // Constant *UniqueKey =
+ // ConstantArray::get(const_cast<ArrayType*>(LLVMArrTy), NumCI);
// that would be a truly unique but dangerous key, because it could lead to
- // creation of constant of arbitrary length (that is the parameter of memset)
- // which were missing in an original module.
+ // the creation of constants of arbitrary length (that is, the parameter of
+ // memset) which were missing in the original module.
Constant *UniqueKey = ConstantStruct::getAnon(
{PoisonValue::get(const_cast<ArrayType *>(LLVMArrTy)),
ConstantInt::get(LLVMBaseTy, Val), ConstantInt::get(LLVMBaseTy, Num)});
diff --git a/llvm/test/CodeGen/SPIRV/var-uniform-const.ll b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
index da02b444e1f4a..eddc1e5f616e0 100644
--- a/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
+++ b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
@@ -18,25 +18,53 @@
; CHECK-SPIRV-DAG: %[[#Const16:]] = OpConstant %[[#Long]] 16
; CHECK-SPIRV-DAG: %[[#One16:]] = OpConstantComposite %[[#Arr16]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]] %[[#One]]
; CHECK-SPIRV-DAG: %[[#Zero16:]] = OpConstantNull %[[#Arr16]]
+
+; The first set of functions.
; CHECK-SPIRV-DAG: %[[#PtrArr3:]] = OpTypePointer UniformConstant %[[#Arr3]]
; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#One3]]
; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#Zero3]]
; CHECK-SPIRV-DAG: %[[#PtrArr16:]] = OpTypePointer UniformConstant %[[#Arr16]]
; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#One16]]
; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#Zero16]]
+
+; The second set of functions.
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#One3]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr3]] UniformConstant %[[#Zero3]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#One16]]
+; CHECK-SPIRV-DAG: OpVariable %[[#PtrArr16]] UniformConstant %[[#Zero16]]
+
+%Vec3 = type { <3 x i8> }
+%Vec16 = type { <16 x i8> }
+
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
; CHECK-SPIRV: OpFunctionEnd
+define spir_kernel void @foo(ptr addrspace(1) noundef align 16 %arg) {
+ %a1 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 3, i1 false)
+ %a2 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a2, i8 1, i64 3, i1 false)
+ ret void
+}
+
; CHECK-SPIRV: OpFunction
; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
; CHECK-SPIRV: OpFunctionEnd
+define spir_kernel void @bar(ptr addrspace(1) noundef align 16 %arg) {
+ %a1 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 16, i1 false)
+ %a2 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
+ call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a2, i8 1, i64 16, i1 false)
+ ret void
+}
-%Vec3 = type { <3 x i8> }
-%Vec16 = type { <16 x i8> }
-
-define spir_kernel void @foo(ptr addrspace(1) noundef align 16 %arg) {
+; CHECK-SPIRV: OpFunction
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const3]] Aligned 4
+; CHECK-SPIRV: OpFunctionEnd
+define spir_kernel void @foo_2(ptr addrspace(1) noundef align 16 %arg) {
%a1 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 3, i1 false)
%a2 = getelementptr inbounds %Vec3, ptr addrspace(1) %arg, i64 1
@@ -44,7 +72,11 @@ define spir_kernel void @foo(ptr addrspace(1) noundef align 16 %arg) {
ret void
}
-define spir_kernel void @bar(ptr addrspace(1) noundef align 16 %arg) {
+; CHECK-SPIRV: OpFunction
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
+; CHECK-SPIRV: OpCopyMemorySized %[[#]] %[[#]] %[[#Const16]] Aligned 4
+; CHECK-SPIRV: OpFunctionEnd
+define spir_kernel void @bar_2(ptr addrspace(1) noundef align 16 %arg) {
%a1 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %a1, i8 0, i64 16, i1 false)
%a2 = getelementptr inbounds %Vec16, ptr addrspace(1) %arg, i64 1
>From 9a21a91922be9cd49a6863b8851d737a84cdcb2c Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 24 Jun 2024 13:06:23 -0700
Subject: [PATCH 4/5] fix 32-bit case
---
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 6 +++++-
llvm/test/CodeGen/SPIRV/var-uniform-const.ll | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index c1b90b0e9d884..3d3f86e5e31cf 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -253,7 +253,11 @@ SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord) {
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
- MachineInstr *ConstInstr = MRI->getVRegDef(ConstReg);
+ MachineInstr *MI = MRI->getVRegDef(ConstReg);
+ MachineInstr *ConstInstr =
+ MI->getOpcode() == SPIRV::G_TRUNC
+ ? MRI->getVRegDef(MI->getOperand(1).getReg())
+ : MI;
if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
if (GI->is(Intrinsic::spv_track_constant)) {
ConstReg = ConstInstr->getOperand(2).getReg();
diff --git a/llvm/test/CodeGen/SPIRV/var-uniform-const.ll b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
index eddc1e5f616e0..6f7c91eb09e90 100644
--- a/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
+++ b/llvm/test/CodeGen/SPIRV/var-uniform-const.ll
@@ -1,8 +1,8 @@
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; TODO: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; CHECK-SPIRV-DAG: %[[#Char:]] = OpTypeInt 8 0
; CHECK-SPIRV-DAG: %[[#Long:]] = OpTypeInt 64 0
>From 8137f56a3c6d4ec7c0ad764e2b205a537caa098e Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 24 Jun 2024 13:15:17 -0700
Subject: [PATCH 5/5] improve pattern matching for constants
---
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 3d3f86e5e31cf..927683ad7e32b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -255,7 +255,7 @@ MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
MachineInstr *ConstInstr =
- MI->getOpcode() == SPIRV::G_TRUNC
+ MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT
? MRI->getVRegDef(MI->getOperand(1).getReg())
: MI;
if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
More information about the llvm-commits
mailing list