[SROA] Fix phi gep unfolding with an alloca not in entry block

Fixes a crash reported in #83494.
This commit is contained in:
Arthur Eubanks
2024-03-07 07:22:33 +00:00
parent a331937197
commit eae4f56cb4
2 changed files with 41 additions and 2 deletions

View File

@@ -4062,10 +4062,14 @@ private:
bool unfoldGEPPhi(GetElementPtrInst &GEPI) {
// To prevent infinitely expanding recursive phis, bail if the GEP pointer
// operand (looking through the phi if it is the phi we want to unfold) is
// an instruction besides an alloca.
// an instruction besides a static alloca.
PHINode *Phi = dyn_cast<PHINode>(GEPI.getPointerOperand());
auto IsInvalidPointerOperand = [](Value *V) {
return isa<Instruction>(V) && !isa<AllocaInst>(V);
if (!isa<Instruction>(V))
return false;
if (auto *AI = dyn_cast<AllocaInst>(V))
return !AI->isStaticAlloca();
return true;
};
if (Phi) {
if (any_of(Phi->operands(), IsInvalidPointerOperand))

View File

@@ -638,6 +638,41 @@ bb3:
ret i1 %icmp
}
define i32 @test_phi_mem2reg_alloca_not_in_entry_block(i1 %arg) {
; CHECK-LABEL: @test_phi_mem2reg_alloca_not_in_entry_block(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8
; CHECK-NEXT: store i64 123, ptr [[ALLOCA]], align 4
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[ALLOCA2:%.*]] = alloca i64, align 8
; CHECK-NEXT: store i64 124, ptr [[ALLOCA]], align 4
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
; CHECK: bb3:
; CHECK-NEXT: br label [[BB4]]
; CHECK: bb4:
; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[BB2]] ], [ [[ALLOCA2]], [[BB3]] ]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
; CHECK-NEXT: ret i32 [[LOAD]]
;
bb:
%alloca = alloca i64
store i64 123, ptr %alloca
br label %bb2
bb2:
%alloca2 = alloca i64
store i64 124, ptr %alloca
br i1 %arg, label %bb3, label %bb4
bb3:
br label %bb4
bb4:
%phi = phi ptr [ %alloca, %bb2 ], [ %alloca2, %bb3 ]
%gep = getelementptr i32, ptr %phi, i64 1
%load = load i32, ptr %gep
ret i32 %load
}
define i64 @test_unfold_phi_duplicate_phi_entry(ptr %arg, i8 %arg1, i1 %arg2) {
; CHECK-LABEL: @test_unfold_phi_duplicate_phi_entry(
; CHECK-NEXT: bb: