[llvm] e3e0613 - [SPIR-V] Ensure that we don't have a dangling BlockAddress constants after internal intrinsic 'spv_switch' is processed (#92390)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 17 02:43:06 PDT 2024
Author: Vyacheslav Levytskyy
Date: 2024-05-17T11:43:02+02:00
New Revision: e3e06135eb16a1b9d84796a6cbb14cac1c1cf543
URL: https://github.com/llvm/llvm-project/commit/e3e06135eb16a1b9d84796a6cbb14cac1c1cf543
DIFF: https://github.com/llvm/llvm-project/commit/e3e06135eb16a1b9d84796a6cbb14cac1c1cf543.diff
LOG: [SPIR-V] Ensure that we don't have a dangling BlockAddress constants after internal intrinsic 'spv_switch' is processed (#92390)
After internal intrinsic 'spv_switch' is processed we need to delete
G_BLOCK_ADDR instructions that were generated to keep track of the
corresponding basic blocks. If we just delete G_BLOCK_ADDR instructions
with BlockAddress operands, this leaves their BasicBlock counterparts in
a "address taken" status. This would make AsmPrinter to generate a
series of unneeded labels of a `"Address of block that was removed by
CodeGen"` kind. This PR is to ensure that we don't have a dangling
BlockAddress constants by zapping the BlockAddress nodes, and only after
that proceed with erasing G_BLOCK_ADDR instructions.
See also https://github.com/llvm/llvm-project/pull/87823 for more
details.
Added:
Modified:
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
llvm/test/CodeGen/SPIRV/branching/switch-range-check.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 6ee5d90d9afe1..9bff23dd96668 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -602,8 +602,25 @@ static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToEraseMI.insert(Next);
}
}
- for (MachineInstr *BlockAddrI : ToEraseMI)
+
+ // If we just delete G_BLOCK_ADDR instructions with BlockAddress operands,
+ // this leaves their BasicBlock counterparts in a "address taken" status. This
+ // would make AsmPrinter to generate a series of unneeded labels of a "Address
+ // of block that was removed by CodeGen" kind. Let's first ensure that we
+ // don't have a dangling BlockAddress constants by zapping the BlockAddress
+ // nodes, and only after that proceed with erasing G_BLOCK_ADDR instructions.
+ Constant *Replacement =
+ ConstantInt::get(Type::getInt32Ty(MF.getFunction().getContext()), 1);
+ for (MachineInstr *BlockAddrI : ToEraseMI) {
+ if (BlockAddrI->getOpcode() == TargetOpcode::G_BLOCK_ADDR) {
+ BlockAddress *BA = const_cast<BlockAddress *>(
+ BlockAddrI->getOperand(1).getBlockAddress());
+ BA->replaceAllUsesWith(
+ ConstantExpr::getIntToPtr(Replacement, BA->getType()));
+ BA->destroyConstant();
+ }
BlockAddrI->eraseFromParent();
+ }
}
static bool isImplicitFallthrough(MachineBasicBlock &MBB) {
diff --git a/llvm/test/CodeGen/SPIRV/branching/switch-range-check.ll b/llvm/test/CodeGen/SPIRV/branching/switch-range-check.ll
index 85a4d4db089cb..f8ce15323aacf 100644
--- a/llvm/test/CodeGen/SPIRV/branching/switch-range-check.ll
+++ b/llvm/test/CodeGen/SPIRV/branching/switch-range-check.ll
@@ -1,10 +1,13 @@
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; CHECK: OpFunction
; CHECK: %[[#Var:]] = OpPhi
; CHECK: OpSwitch %[[#Var]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]] [[#]] %[[#]]
; CHECK-COUNT-11: OpBranch
; CHECK-NOT: OpBranch
+; CHECK: OpReturn
+; CHECK-NEXT: OpFunctionEnd
define spir_func void @foo(i64 noundef %addr, i64 noundef %as) {
entry:
More information about the llvm-commits
mailing list