Skip to content

Commit 3c2f185

Browse files
Merge pull request #4037 from aschwaighofer/instcombine_phi_swifterror_fix_rdar89865485
InstCombine: Can't fold a phi arg load into the phi if the load is from a swifterror address
2 parents 0a70434 + f63d977 commit 3c2f185

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
411411
Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
412412
LoadInst *FirstLI = cast<LoadInst>(PN.getIncomingValue(0));
413413

414+
// Can't forward swifterror through a phi.
415+
if (FirstLI->getOperand(0)->isSwiftError())
416+
return nullptr;
417+
414418
// FIXME: This is overconservative; this transform is allowed in some cases
415419
// for atomic operations.
416420
if (FirstLI->isAtomic())
@@ -444,6 +448,10 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
444448
if (!LI || !LI->hasOneUser())
445449
return nullptr;
446450

451+
// Can't forward swifterror through a phi.
452+
if (LI->getOperand(0)->isSwiftError())
453+
return nullptr;
454+
447455
// We can't sink the load if the loaded value could be modified between
448456
// the load and the PHI.
449457
if (LI->isVolatile() != isVolatile ||

llvm/test/Transforms/InstCombine/phi-equal-incoming-pointers.ll

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,3 +573,69 @@ exit:
573573
%res = select i1 %cond2, i8 %res.phi, i8 %res.load
574574
ret i8 %res
575575
}
576+
577+
; `swifterror` addresses are restricted to load and stores and call arguments.
578+
declare void @takeAddress(i8** swifterror)
579+
580+
define i8* @test_dont_optimize_swifterror(i1 %cond, i1 %cond2, i8* %ptr) {
581+
; INSTCOMBINE-LABEL: @test_dont_optimize_swifterror(
582+
; INSTCOMBINE-NEXT: entry:
583+
; INSTCOMBINE-NEXT: [[OBJ:%.*]] = alloca swifterror i8*, align 8
584+
; INSTCOMBINE-NEXT: [[OBJ2:%.*]] = alloca swifterror i8*, align 8
585+
; INSTCOMBINE-NEXT: call void @takeAddress(i8** nonnull swifterror [[OBJ]])
586+
; INSTCOMBINE-NEXT: call void @takeAddress(i8** nonnull swifterror [[OBJ2]])
587+
; INSTCOMBINE-NEXT: store i8* [[PTR:%.*]], i8** [[OBJ]], align 8
588+
; INSTCOMBINE-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
589+
; INSTCOMBINE: bb1:
590+
; INSTCOMBINE-NEXT: [[RES1:%.*]] = load i8*, i8** [[OBJ]], align 8
591+
; INSTCOMBINE-NEXT: br label [[EXIT:%.*]]
592+
; INSTCOMBINE: bb2:
593+
; INSTCOMBINE-NEXT: [[RES2:%.*]] = load i8*, i8** [[OBJ2]], align 8
594+
; INSTCOMBINE-NEXT: br label [[EXIT]]
595+
; INSTCOMBINE: exit:
596+
; INSTCOMBINE-NEXT: [[RES_PHI:%.*]] = phi i8* [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
597+
; INSTCOMBINE-NEXT: store i8* null, i8** [[OBJ]], align 8
598+
; INSTCOMBINE-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i8* [[RES_PHI]], i8* null
599+
; INSTCOMBINE-NEXT: ret i8* [[RES]]
600+
;
601+
; INSTCOMBINEGVN-LABEL: @test_dont_optimize_swifterror(
602+
; INSTCOMBINEGVN-NEXT: entry:
603+
; INSTCOMBINEGVN-NEXT: [[OBJ:%.*]] = alloca swifterror i8*, align 8
604+
; INSTCOMBINEGVN-NEXT: [[OBJ2:%.*]] = alloca swifterror i8*, align 8
605+
; INSTCOMBINEGVN-NEXT: call void @takeAddress(i8** nonnull swifterror [[OBJ]])
606+
; INSTCOMBINEGVN-NEXT: call void @takeAddress(i8** nonnull swifterror [[OBJ2]])
607+
; INSTCOMBINEGVN-NEXT: store i8* [[PTR:%.*]], i8** [[OBJ]], align 8
608+
; INSTCOMBINEGVN-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
609+
; INSTCOMBINEGVN: bb1:
610+
; INSTCOMBINEGVN-NEXT: br label [[EXIT:%.*]]
611+
; INSTCOMBINEGVN: bb2:
612+
; INSTCOMBINEGVN-NEXT: [[RES2:%.*]] = load i8*, i8** [[OBJ2]], align 8
613+
; INSTCOMBINEGVN-NEXT: br label [[EXIT]]
614+
; INSTCOMBINEGVN: exit:
615+
; INSTCOMBINEGVN-NEXT: [[RES_PHI:%.*]] = phi i8* [ [[PTR]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
616+
; INSTCOMBINEGVN-NEXT: store i8* null, i8** [[OBJ]], align 8
617+
; INSTCOMBINEGVN-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i8* [[RES_PHI]], i8* null
618+
; INSTCOMBINEGVN-NEXT: ret i8* [[RES]]
619+
;
620+
entry:
621+
%obj = alloca swifterror i8*, align 8
622+
%obj2 = alloca swifterror i8*, align 8
623+
call void @takeAddress(i8** swifterror %obj)
624+
call void @takeAddress(i8** swifterror %obj2)
625+
store i8* %ptr, i8** %obj, align 8
626+
br i1 %cond, label %bb1, label %bb2
627+
628+
bb1: ; preds = %entry
629+
%res1 = load i8*, i8** %obj, align 8
630+
br label %exit
631+
632+
bb2: ; preds = %entry
633+
%res2 = load i8*, i8** %obj2, align 8
634+
br label %exit
635+
636+
exit: ; preds = %bb2, %bb1
637+
%res.phi = phi i8* [ %res1, %bb1 ], [ %res2, %bb2 ]
638+
store i8* null, i8** %obj, align 8
639+
%res = select i1 %cond2, i8* %res.phi, i8* null
640+
ret i8* %res
641+
}

0 commit comments

Comments
 (0)