Skip to content

[SPIR-V]: Improve pattern matching to recognize a composite constant to be a constant #96286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 24, 2024

Conversation

VyacheslavLevytskyy
Copy link
Contributor

This PR is to fix #96285 by:

  • improve pattern matching to recognize an aggregate constant to be a constant
  • do not emit Bitcast for an aggregate type

@llvmbot
Copy link
Member

llvmbot commented Jun 21, 2024

@llvm/pr-subscribers-backend-spir-v

Author: Vyacheslav Levytskyy (VyacheslavLevytskyy)

Changes

This PR is to fix #96285 by:

  • improve pattern matching to recognize an aggregate constant to be a constant
  • do not emit Bitcast for an aggregate type

Full diff: https://github.com/llvm/llvm-project/pull/96286.diff

3 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h (+6)
  • (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+14-3)
  • (added) llvm/test/CodeGen/SPIRV/const-array-in-struct.ll (+21)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index db01f68f48de9..2182ad70cab46 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -327,6 +327,12 @@ class SPIRVGlobalRegistry {
     return Ret;
   }
 
+  // Return true if the type is an aggregate type.
+  bool isAggregateType(SPIRVType *Type) const {
+    return Type && (Type->getOpcode() == SPIRV::OpTypeStruct &&
+                    Type->getOpcode() == SPIRV::OpTypeArray);
+  }
+
   // Whether the given VReg has an OpTypeXXX instruction mapped to it with the
   // given opcode (e.g. OpTypeFloat).
   bool isScalarOfType(Register VReg, unsigned TypeOpcode) const;
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index d7b96b28445d6..7a538736c77d6 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1451,8 +1451,18 @@ static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef) {
     if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
       OpDef = RefDef;
   }
-  return OpDef->getOpcode() == TargetOpcode::G_CONSTANT ||
-         OpDef->getOpcode() == TargetOpcode::G_FCONSTANT;
+  unsigned Opcode = OpDef->getOpcode();
+  switch (Opcode) {
+  case TargetOpcode::G_CONSTANT:
+  case TargetOpcode::G_FCONSTANT:
+    return true;
+  case TargetOpcode::G_INTRINSIC:
+  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
+  case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
+    return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
+           Intrinsic::spv_const_composite;
+  }
+  return false;
 }
 
 // Return true if the virtual register represents a constant
@@ -1883,7 +1893,8 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
     SPIRVType *OpDefine = MRI->getVRegDef(OpReg);
     SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpReg);
     if (!OpDefine || !OpType || isConstReg(MRI, OpDefine) ||
-        OpDefine->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
+        OpDefine->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST ||
+        GR.isAggregateType(OpType)) {
       // The case of G_ADDRSPACE_CAST inside spv_const_composite() is processed
       // by selectAddrSpaceCast()
       CompositeArgs.push_back(OpReg);
diff --git a/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll b/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll
new file mode 100644
index 0000000000000..ac39f3d28d073
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/const-array-in-struct.ll
@@ -0,0 +1,21 @@
+; 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 %}
+
+; 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: %[[#IntTy:]] = OpTypeInt 32 0
+; CHECK-SPIRV: %[[#Const16:]] = OpConstant %[[#IntTy]] 16
+; CHECK-SPIRV: %[[#ArrayTy:]] = OpTypeArray %[[#IntTy]] %[[#Const16]]
+; CHECK-SPIRV: %[[#StructTy:]] = OpTypeStruct %[[#ArrayTy]]
+; CHECK-SPIRV-COUNT-16: %[[#]] = OpConstant %[[#IntTy]] {{[0-9]+}}
+; CHECK-SPIRV: %[[#ConstArray:]] = OpConstantComposite %[[#ArrayTy]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]]
+; CHECK-SPIRV: %[[#]] = OpConstantComposite %[[#StructTy]] %[[#ConstArray]]
+
+%struct_array_16i32 = type { [16 x i32] }
+
+@G = private unnamed_addr addrspace(1) constant %struct_array_16i32 { [16 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15] }, align 4
+
+define spir_kernel void @test() {
+  ret void
+}

@VyacheslavLevytskyy VyacheslavLevytskyy changed the title [SPIR-V]: Improve pattern matching to recognize an aggregate constant to be a constant [SPIR-V]: Improve pattern matching to recognize a composite constant to be a constant Jun 21, 2024
@VyacheslavLevytskyy VyacheslavLevytskyy merged commit b0efde6 into llvm:main Jun 24, 2024
8 checks passed
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
…to be a constant (llvm#96286)

This PR is to fix llvm#96285 by:
* improve pattern matching to recognize an aggregate constant to be a
constant
* do not emit Bitcast for an aggregate type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SPIR-V] Creation of a constant struct with an array field leads to invalid SPIR-V code produced
3 participants