Skip to content

Commit

Permalink
[InstCombine] Fix a crash in PointerReplacer (#98987)
Browse files Browse the repository at this point in the history
A crash could happen in `PointerReplacer::replace` when constructing a
new
select instruction and there is no replacement for one of its operand.
This can
happen when the operand is a load instruction that has been replaced
earlier
such that the operand itself is already the new value. In this case, it
is not
in the replacement map and `getReplacement` simply returns nullptr.

Fix SWDEV-472192.
  • Loading branch information
shiltian authored Jul 16, 2024
1 parent a05724a commit f38baad
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
11 changes: 8 additions & 3 deletions llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,14 @@ void PointerReplacer::replace(Instruction *I) {
NewI->setNoWrapFlags(GEP->getNoWrapFlags());
WorkMap[GEP] = NewI;
} else if (auto *SI = dyn_cast<SelectInst>(I)) {
auto *NewSI = SelectInst::Create(
SI->getCondition(), getReplacement(SI->getTrueValue()),
getReplacement(SI->getFalseValue()), SI->getName(), nullptr, SI);
Value *TrueValue = SI->getTrueValue();
Value *FalseValue = SI->getFalseValue();
if (Value *Replacement = getReplacement(TrueValue))
TrueValue = Replacement;
if (Value *Replacement = getReplacement(FalseValue))
FalseValue = Replacement;
auto *NewSI = SelectInst::Create(SI->getCondition(), TrueValue, FalseValue,
SI->getName(), nullptr, SI);
IC.InsertNewInstWith(NewSI, SI->getIterator());
NewSI->takeName(SI);
WorkMap[SI] = NewSI;
Expand Down
33 changes: 33 additions & 0 deletions llvm/test/Transforms/InstCombine/AMDGPU/select-from-load.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s
; REQUIRES: amdgpu-registered-target

target triple = "amdgcn-amd-amdhsa"

%anon = type { i32, [8 x ptr], ptr }

define void @foo(ptr addrspace(4) byref(%anon) align 8 %0) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr addrspace(4) [[TMP0:%.*]], align 8
; CHECK-NEXT: br label [[FOR_COND10:%.*]]
; CHECK: for.cond10:
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 8
; CHECK-NEXT: store i64 [[TMP2]], ptr addrspace(1) null, align 8
; CHECK-NEXT: br label [[FOR_COND10]]
;
entry:
%coerce = alloca %anon, addrspace(5)
call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) %coerce, ptr addrspace(4) %0, i64 0, i1 false)
%asc = addrspacecast ptr addrspace(5) %coerce to ptr
%load = load ptr, ptr addrspace(5) %coerce
%retval.0.i = select i1 false, ptr %asc, ptr %load
br label %for.cond10

for.cond10: ; preds = %for.cond10, %entry
%3 = load i64, ptr %retval.0.i
store i64 %3, ptr addrspace(1) null
br label %for.cond10
}

declare void @llvm.memcpy.p5.p4.i64(ptr addrspace(5), ptr addrspace(4), i64, i1 immarg)

0 comments on commit f38baad

Please sign in to comment.