Skip to content

Commit c502a99

Browse files
VyacheslavLevytskyyAlexisPerry
authored andcommitted
[SPIR-V] Improve pattern matching and tracking of constant integers (llvm#96615)
This PR fixes the issue llvm#96614 by improve pattern matching and tracking of constant integers. The attached test is successful if it doesn't crash and generate valid SPIR-V code for both 32 and 64 bits targets.
1 parent 2094274 commit c502a99

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,15 +1802,18 @@ bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
18021802
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
18031803
assert(MO.isReg());
18041804
const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
1805-
if (TypeInst->getOpcode() != SPIRV::ASSIGN_TYPE)
1806-
return false;
1807-
assert(TypeInst->getOperand(1).isReg());
1808-
MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
1809-
return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
1805+
if (TypeInst->getOpcode() == SPIRV::ASSIGN_TYPE) {
1806+
assert(TypeInst->getOperand(1).isReg());
1807+
MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
1808+
return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
1809+
}
1810+
return TypeInst->getOpcode() == SPIRV::OpConstantI;
18101811
}
18111812

18121813
static int64_t foldImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
18131814
const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
1815+
if (TypeInst->getOpcode() == SPIRV::OpConstantI)
1816+
return TypeInst->getOperand(2).getImm();
18141817
MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
18151818
assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
18161819
return ImmInst->getOperand(1).getCImm()->getZExtValue();

llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
415415

416416
MachineRegisterInfo &MRI = MF.getRegInfo();
417417
SmallVector<MachineInstr *, 10> ToErase;
418+
DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
418419

419420
for (MachineBasicBlock *MBB : post_order(&MF)) {
420421
if (MBB->empty())
@@ -466,6 +467,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
466467
// %rctmp = G_CONSTANT ty Val
467468
// %rc = ASSIGN_TYPE %rctmp, %cty
468469
Register Reg = MI.getOperand(0).getReg();
470+
bool NeedAssignType = true;
469471
if (MRI.hasOneUse(Reg)) {
470472
MachineInstr &UseMI = *MRI.use_instr_begin(Reg);
471473
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
@@ -478,7 +480,20 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
478480
Ty = TargetExtIt == TargetExtConstTypes.end()
479481
? MI.getOperand(1).getCImm()->getType()
480482
: TargetExtIt->second;
481-
GR->add(MI.getOperand(1).getCImm(), &MF, Reg);
483+
const ConstantInt *OpCI = MI.getOperand(1).getCImm();
484+
Register PrimaryReg = GR->find(OpCI, &MF);
485+
if (!PrimaryReg.isValid()) {
486+
GR->add(OpCI, &MF, Reg);
487+
} else if (PrimaryReg != Reg &&
488+
MRI.getType(Reg) == MRI.getType(PrimaryReg)) {
489+
auto *RCReg = MRI.getRegClassOrNull(Reg);
490+
auto *RCPrimary = MRI.getRegClassOrNull(PrimaryReg);
491+
if (!RCReg || RCPrimary == RCReg) {
492+
RegsAlreadyAddedToDT[&MI] = PrimaryReg;
493+
ToErase.push_back(&MI);
494+
NeedAssignType = false;
495+
}
496+
}
482497
} else if (MIOp == TargetOpcode::G_FCONSTANT) {
483498
Ty = MI.getOperand(1).getFPImm()->getType();
484499
} else {
@@ -497,7 +512,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
497512
MI.getNumExplicitOperands() - MI.getNumExplicitDefs();
498513
Ty = VectorType::get(ElemTy, NumElts, false);
499514
}
500-
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
515+
if (NeedAssignType)
516+
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
501517
} else if (MIOp == TargetOpcode::G_GLOBAL_VALUE) {
502518
propagateSPIRVType(&MI, GR, MRI, MIB);
503519
}
@@ -508,8 +524,12 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
508524
--MII;
509525
}
510526
}
511-
for (MachineInstr *MI : ToErase)
527+
for (MachineInstr *MI : ToErase) {
528+
auto It = RegsAlreadyAddedToDT.find(MI);
529+
if (RegsAlreadyAddedToDT.contains(MI))
530+
MRI.replaceRegWith(MI->getOperand(0).getReg(), It->second);
512531
MI->eraseFromParent();
532+
}
513533

514534
// Address the case when IRTranslator introduces instructions with new
515535
// registers without SPIRVType associated.

llvm/test/CodeGen/SPIRV/const-nested-vecs.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
1+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV64
22
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
33

4-
; TODO: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5-
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
4+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV32
5+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
66

77
; CHECK-SPIRV: OpName %[[#Var:]] "var"
88
; CHECK-SPIRV: OpName %[[#GVar:]] "g_var"
@@ -24,8 +24,9 @@
2424
; CHECK-SPIRV-DAG: %[[#PtrArr2V2CharTy:]] = OpTypePointer CrossWorkgroup %[[#Arr2V2CharTy]]
2525
; CHECK-SPIRV-DAG: %[[#IntZero:]] = OpConstantNull %[[#IntTy]]
2626
; CHECK-SPIRV-DAG: %[[#LongZero:]] = OpConstantNull %[[#LongTy]]
27-
; CHECK-SPIRV-DAG: %[[#ConstLong2:]] = OpConstant %[[#LongTy]] 2
28-
; CHECK-SPIRV-DAG: %[[#PvarInit:]] = OpSpecConstantOp %[[#PtrCharTy]] 70 %[[#VarV2Char:]] %[[#IntZero]] %[[#ConstLong2]]
27+
; CHECK-SPIRV64-DAG: %[[#ConstLong2:]] = OpConstant %[[#LongTy]] 2
28+
; CHECK-SPIRV64-DAG: %[[#PvarInit:]] = OpSpecConstantOp %[[#PtrCharTy]] 70 %[[#VarV2Char:]] %[[#IntZero]] %[[#ConstLong2]]
29+
; CHECK-SPIRV32-DAG: %[[#PvarInit:]] = OpSpecConstantOp %[[#PtrCharTy]] 70 %[[#VarV2Char:]] %[[#IntZero]] %[[#Const2]]
2930
; CHECK-SPIRV-DAG: %[[#PtrPtrCharTy:]] = OpTypePointer CrossWorkgroup %[[#PtrCharTy]]
3031
; CHECK-SPIRV-DAG: %[[#AVar]] = OpVariable %[[#PtrArr2V2CharTy]] CrossWorkgroup %[[#Arr2V2Char]]
3132
; CHECK-SPIRV-DAG: %[[#PVar]] = OpVariable %[[#PtrPtrCharTy]] CrossWorkgroup %[[#PvarInit]]

llvm/test/CodeGen/SPIRV/pointers/global-zeroinitializer.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
; CHECK: OpFunction
1717

1818
@var = addrspace(1) global <2 x i8> zeroinitializer
19-
;@var = addrspace(1) global <2 x i8> <i8 1, i8 1>
2019

2120
define spir_kernel void @foo() {
2221
entry:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; The goal of the test is to check that collisions between explicit integer constants and
2+
; integer constants added automatically by IR Translator are resolved correctly both for
3+
; 32- and 64-bits platforms. The test is successful if it doesn't crash and generate valid
4+
; SPIR-V code for both 32 and 64 bits targets.
5+
6+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV64
7+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
8+
9+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV32
10+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
11+
12+
; CHECK-SPIRV64-DAG: %[[#IntTy:]] = OpTypeInt 64 0
13+
; CHECK-SPIRV32-DAG: %[[#IntTy:]] = OpTypeInt 32 0
14+
; CHECK-SPIRV-DAG: %[[#Const2:]] = OpConstant %[[#IntTy]] 2
15+
; CHECK-SPIRV-DAG: %[[#]] = OpSpecConstantOp %[[#]] 70 %[[#]] %[[#]] %[[#Const2]]
16+
; CHECK-SPIRV: OpFunction
17+
18+
@a_var = addrspace(1) global [2 x i8] [i8 1, i8 1]
19+
@p_var = addrspace(1) global ptr addrspace(1) getelementptr (i8, ptr addrspace(1) @a_var, i64 2)
20+
21+
define spir_func void @foo() {
22+
entry:
23+
ret void
24+
}

0 commit comments

Comments
 (0)