Skip to content

Commit ddc484b

Browse files
committed
[InstCombine] Handle select inst when eliminating constant memcpy
Allow iterating through SelectInst use of the alloca when checking if it is only ever overwritten from constant memory. Recursively determine if the SelectInst is replacable and insert it into the Worklist if so. Finally, define a new SelectInst to replace the old one, with both of it's values replaced according to the WorkMap. Differential Revision: https://reviews.llvm.org/D136524
1 parent 7d0145c commit ddc484b

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V,
7272
continue;
7373
}
7474

75-
if (isa<PHINode>(I)) {
75+
if (isa<PHINode, SelectInst>(I)) {
7676
// We set IsOffset=true, to forbid the memcpy from occurring after the
7777
// phi: If one of the phi operands is not based on the alloca, we
7878
// would incorrectly omit a write.
7979
Worklist.emplace_back(I, true);
8080
continue;
8181
}
82-
if (isa<BitCastInst>(I) || isa<AddrSpaceCastInst>(I)) {
82+
if (isa<BitCastInst, AddrSpaceCastInst>(I)) {
8383
// If uses of the bitcast are ok, we are ok.
8484
Worklist.emplace_back(I, IsOffset);
8585
continue;
@@ -320,6 +320,19 @@ bool PointerReplacer::collectUsersRecursive(Instruction &I) {
320320
Worklist.insert(PHI);
321321
if (!collectUsersRecursive(*PHI))
322322
return false;
323+
} else if (auto *SI = dyn_cast<SelectInst>(Inst)) {
324+
if (!isa<Instruction>(SI->getTrueValue()) ||
325+
!isa<Instruction>(SI->getFalseValue()))
326+
return false;
327+
328+
if (!isAvailable(cast<Instruction>(SI->getTrueValue())) ||
329+
!isAvailable(cast<Instruction>(SI->getFalseValue()))) {
330+
ValuesToRevisit.insert(Inst);
331+
continue;
332+
}
333+
Worklist.insert(SI);
334+
if (!collectUsersRecursive(*SI))
335+
return false;
323336
} else if (isa<GetElementPtrInst, BitCastInst>(Inst)) {
324337
Worklist.insert(Inst);
325338
if (!collectUsersRecursive(*Inst))
@@ -385,6 +398,13 @@ void PointerReplacer::replace(Instruction *I) {
385398
IC.InsertNewInstWith(NewI, *BC);
386399
NewI->takeName(BC);
387400
WorkMap[BC] = NewI;
401+
} else if (auto *SI = dyn_cast<SelectInst>(I)) {
402+
auto *NewSI = SelectInst::Create(
403+
SI->getCondition(), getReplacement(SI->getTrueValue()),
404+
getReplacement(SI->getFalseValue()), SI->getName(), nullptr, SI);
405+
IC.InsertNewInstWith(NewSI, *SI);
406+
NewSI->takeName(SI);
407+
WorkMap[SI] = NewSI;
388408
} else if (auto *MemCpy = dyn_cast<MemTransferInst>(I)) {
389409
auto *SrcV = getReplacement(MemCpy->getRawSource());
390410
// The pointer may appear in the destination of a copy, but we don't want to

llvm/test/Transforms/InstCombine/ptr-replace-alloca.ll

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,7 @@ exit:
366366
define i8 @select_same_addrspace_remove_alloca(i1 %cond, ptr %p) {
367367
; CHECK-LABEL: @select_same_addrspace_remove_alloca(
368368
; CHECK-NEXT: entry:
369-
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1
370-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr noundef nonnull align 16 dereferenceable(32) @g1, i64 32, i1 false)
371-
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr [[ALLOCA]], ptr [[P:%.*]]
369+
; CHECK-NEXT: [[PTR:%.*]] = select i1 [[COND:%.*]], ptr @g1, ptr [[P:%.*]]
372370
; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[PTR]], align 1
373371
; CHECK-NEXT: ret i8 [[LOAD]]
374372
;
@@ -417,13 +415,8 @@ entry:
417415
define i8 @select_diff_addrspace_remove_alloca(i1 %cond, ptr %p) {
418416
; CHECK-LABEL: @select_diff_addrspace_remove_alloca(
419417
; CHECK-NEXT: entry:
420-
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [32 x i8], align 1
421-
; CHECK-NEXT: call void @llvm.memcpy.p0.p1.i64(ptr noundef nonnull align 1 dereferenceable(32) [[ALLOCA]], ptr addrspace(1) noundef align 16 dereferenceable(32) @g2, i64 32, i1 false)
422-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [32 x i8], ptr [[ALLOCA]], i64 0, i64 2
423-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[ALLOCA]], ptr [[GEP]]
424-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[SEL]], i64 4
425-
; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[GEP2]], align 1
426-
; CHECK-NEXT: ret i8 [[LOAD]]
418+
; CHECK-NOT: [[ALLOCA:%.*]] = alloca [32 x i8]
419+
; CHECK-NEXT: ret i8 0
427420
;
428421
entry:
429422
%alloca = alloca [32 x i8]

0 commit comments

Comments
 (0)