Skip to content
Open
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
10 changes: 9 additions & 1 deletion llvm/lib/IR/ReplaceConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ bool llvm::convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts,

// Replace those expandable operands with instructions
bool Changed = false;
// We need to cache the instructions we've already expanded to avoid expanding
// the same constant multiple times in the same basic block, which is
// problematic when the same constant is used in a phi node multiple times.
DenseMap<std::pair<Constant *, BasicBlock *>, SmallVector<Instruction *, 4>>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose the expansion of the SmallVector will not cause any trouble in the map, since it is fixed size, and when it needs expansion, it uses heap and its original location will not be moved.

ConstantToInstructionMap;
while (!InstructionWorklist.empty()) {
Instruction *I = InstructionWorklist.pop_back_val();
DebugLoc Loc = I->getDebugLoc();
Expand All @@ -105,7 +110,10 @@ bool llvm::convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts,
if (auto *C = dyn_cast<Constant>(U.get())) {
if (ExpandableUsers.contains(C)) {
Changed = true;
auto NewInsts = expandUser(BI, C);
SmallVector<Instruction *, 4> &NewInsts =
ConstantToInstructionMap[std::make_pair(C, BI->getParent())];
if (NewInsts.empty())
NewInsts = expandUser(BI, C);
Copy link
Contributor

Choose a reason for hiding this comment

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

when NewInsts.empty() is true, there will be a copy to NewInsts after it is default constructed. Can we avoid the copy?

for (auto *NI : NewInsts)
NI->setDebugLoc(Loc);
InstructionWorklist.insert_range(NewInsts);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-lower-module-lds %s -o - | FileCheck %s
; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-lower-module-lds %s -o - | FileCheck %s

@lds = internal unnamed_addr addrspace(3) global [6144 x half] poison, align 2

define amdgpu_kernel void @test(ptr addrspace(1) %out) {
; CHECK-LABEL: define amdgpu_kernel void @test(
; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: switch i32 0, label %[[BB_3:.*]] [
; CHECK-NEXT: i32 18, label %[[BB_2:.*]]
; CHECK-NEXT: i32 1, label %[[BB_2]]
; CHECK-NEXT: i32 0, label %[[BB_3]]
; CHECK-NEXT: ]
; CHECK: [[BB_1:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr addrspace(3) @llvm.amdgcn.kernel.test.lds to ptr
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64
; CHECK-NEXT: switch i32 0, label %[[BB_3]] [
; CHECK-NEXT: i32 18, label %[[BB_2]]
; CHECK-NEXT: i32 1, label %[[BB_2]]
; CHECK-NEXT: i32 0, label %[[BB_3]]
; CHECK-NEXT: ]
; CHECK: [[BB_2]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[TMP1]], %[[BB_1]] ], [ [[TMP1]], %[[BB_1]] ], [ 10, %[[ENTRY]] ], [ 10, %[[ENTRY]] ]
; CHECK-NEXT: store i64 [[PHI]], ptr addrspace(1) [[OUT]], align 8
; CHECK-NEXT: br label %[[BB_3]]
; CHECK: [[BB_3]]:
; CHECK-NEXT: ret void
;
entry:
switch i32 0, label %bb.3 [
i32 18, label %bb.2
i32 1, label %bb.2
i32 0, label %bb.3
]
bb.1:
switch i32 0, label %bb.3 [
i32 18, label %bb.2
i32 1, label %bb.2
i32 0, label %bb.3
]

bb.2:
%phi = phi i64 [ ptrtoint (ptr addrspacecast (ptr addrspace(3) @lds to ptr) to i64), %bb.1 ], [ ptrtoint (ptr addrspacecast (ptr addrspace(3) @lds to ptr) to i64), %bb.1 ], [10, %entry], [10, %entry]
Copy link
Contributor Author

@shiltian shiltian Nov 22, 2025

Choose a reason for hiding this comment

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

On a second thought, should we deduplicate the incoming BBs when we construct a phi node? In this way we don't need to fix anything else.

store i64 %phi, ptr addrspace(1) %out, align 8
br label %bb.3

bb.3:
ret void
}
Loading