Skip to content

Commit 2d08c42

Browse files
committed
InstCombine: Fix a crash in PointerReplacer when constructing a new PHI (llvm#130256)
When constructing a PHI node in `PointerReplacer::replace`, the incoming operands are expected to have already been replaced and in the replacement map. However, when one of the incoming operands is a load, the search of the map is unsuccessful, and a nullptr is returned from `getReplacement`. The reason is that, when a load is replaced, all the uses of the load has been actually replaced by the new load. It is useless to insert the original load into the map. Instead, we should place the new load into the map to meet the expectation of the later map search. Fixes: SWDEV-516420
1 parent f26e346 commit 2d08c42

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,10 @@ void PointerReplacer::replace(Instruction *I) {
374374

375375
IC.InsertNewInstWith(NewI, LT->getIterator());
376376
IC.replaceInstUsesWith(*LT, NewI);
377-
WorkMap[LT] = NewI;
377+
// LT has actually been replaced by NewI. It is useless to insert LT into
378+
// the map. Instead, we insert NewI into the map to indicate this is the
379+
// replacement (new value).
380+
WorkMap[NewI] = NewI;
378381
} else if (auto *PHI = dyn_cast<PHINode>(I)) {
379382
Type *NewTy = getReplacement(PHI->getIncomingValue(0))->getType();
380383
auto *NewPHI = PHINode::Create(NewTy, PHI->getNumIncomingValues(),
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s
3+
4+
target triple = "amdgcn-amd-amdhsa"
5+
6+
%double_double = type { double, double }
7+
8+
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
9+
10+
define void @_test(ptr addrspace(4) byref(%double_double) align 8 %in) {
11+
; CHECK-LABEL: define void @_test(
12+
; CHECK-SAME: ptr addrspace(4) byref([[DOUBLE_DOUBLE:%.*]]) align 8 [[IN:%.*]]) {
13+
; CHECK-NEXT: [[ENTRY:.*]]:
14+
; CHECK-NEXT: [[ALPHA_UNION:%.*]] = addrspacecast ptr addrspace(4) [[IN]] to ptr
15+
; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(5) null, align 1
16+
; CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[LOAD]] to i1
17+
; CHECK-NEXT: br i1 [[LOADEDV]], label %[[COND_END:.*]], label %[[COND_FALSE:.*]]
18+
; CHECK: [[COND_FALSE]]:
19+
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(4) [[IN]], align 8
20+
; CHECK-NEXT: br label %[[COND_END]]
21+
; CHECK: [[COND_END]]:
22+
; CHECK-NEXT: [[COND1:%.*]] = phi ptr [ [[TMP0]], %[[COND_FALSE]] ], [ [[ALPHA_UNION]], %[[ENTRY]] ]
23+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) poison, ptr noundef nonnull align 1 dereferenceable(16) [[COND1]], i64 16, i1 false)
24+
; CHECK-NEXT: ret void
25+
;
26+
entry:
27+
%coerce = alloca %double_double, align 8, addrspace(5)
28+
%alpha_union = addrspacecast ptr addrspace(5) %coerce to ptr
29+
call void @llvm.memcpy.p5.p4.i64(ptr addrspace(5) align 8 %coerce, ptr addrspace(4) align 8 %in, i64 16, i1 false)
30+
%load1 = load i8, ptr addrspace(5) null, align 1
31+
%loadedv = trunc i8 %load1 to i1
32+
br i1 %loadedv, label %cond.end, label %cond.false
33+
34+
cond.false:
35+
%load2 = load ptr, ptr addrspace(5) %coerce, align 8
36+
br label %cond.end
37+
38+
cond.end:
39+
%cond = phi ptr [ %load2, %cond.false ], [ %alpha_union, %entry ]
40+
call void @llvm.memcpy.p0.p0.i64(ptr poison, ptr %cond, i64 16, i1 false)
41+
ret void
42+
}

0 commit comments

Comments
 (0)