Skip to content

Commit bba1558

Browse files
pccgithub-actions[bot]
authored andcommitted
Automerge: Utils: Inhibit load/store folding through phis for llvm.protected.field.ptr.
Protected pointer field loads/stores should be paired with the intrinsic to avoid unnecessary address escapes. Reviewers: nikic Reviewed By: nikic Pull Request: llvm/llvm-project#151649
2 parents 9d32e4c + e60d62b commit bba1558

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,7 @@ static bool isSafeAndProfitableToSinkLoad(LoadInst *L) {
698698
Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
699699
LoadInst *FirstLI = cast<LoadInst>(PN.getIncomingValue(0));
700700

701-
// Can't forward swifterror through a phi.
702-
if (FirstLI->getOperand(0)->isSwiftError())
701+
if (!canReplaceOperandWithVariable(FirstLI, 0))
703702
return nullptr;
704703

705704
// FIXME: This is overconservative; this transform is allowed in some cases
@@ -738,8 +737,7 @@ Instruction *InstCombinerImpl::foldPHIArgLoadIntoPHI(PHINode &PN) {
738737
LI->getPointerAddressSpace() != LoadAddrSpace)
739738
return nullptr;
740739

741-
// Can't forward swifterror through a phi.
742-
if (LI->getOperand(0)->isSwiftError())
740+
if (!canReplaceOperandWithVariable(LI, 0))
743741
return nullptr;
744742

745743
// We can't sink the load if the loaded value could be modified between

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3884,6 +3884,12 @@ bool llvm::canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx) {
38843884
if (Op->isSwiftError())
38853885
return false;
38863886

3887+
// Protected pointer field loads/stores should be paired with the intrinsic
3888+
// to avoid unnecessary address escapes.
3889+
if (auto *II = dyn_cast<IntrinsicInst>(Op))
3890+
if (II->getIntrinsicID() == Intrinsic::protected_field_ptr)
3891+
return false;
3892+
38873893
// Cannot replace alloca argument with phi/select.
38883894
if (I->isLifetimeStartOrEnd())
38893895
return false;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -O2 -S < %s | FileCheck %s
3+
4+
; Test that no optimization run at -O2 moves the loads into the exit block,
5+
; as this causes unnecessary address escapes with pointer field protection.
6+
7+
define ptr @phi_prot_ptr(i1 %sel, ptr %p1, ptr %p2) {
8+
; CHECK-LABEL: define ptr @phi_prot_ptr(
9+
; CHECK-SAME: i1 [[SEL:%.*]], ptr readonly [[P1:%.*]], ptr readonly [[P2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
10+
; CHECK-NEXT: br i1 [[SEL]], label %[[T:.*]], label %[[F:.*]]
11+
; CHECK: [[T]]:
12+
; CHECK-NEXT: [[PROTP1:%.*]] = tail call ptr @llvm.protected.field.ptr.p0(ptr [[P1]], i64 1, i1 true)
13+
; CHECK-NEXT: [[LOAD1:%.*]] = load ptr, ptr [[PROTP1]], align 8
14+
; CHECK-NEXT: br label %[[EXIT:.*]]
15+
; CHECK: [[F]]:
16+
; CHECK-NEXT: [[PROTP2:%.*]] = tail call ptr @llvm.protected.field.ptr.p0(ptr [[P2]], i64 2, i1 true)
17+
; CHECK-NEXT: [[LOAD2:%.*]] = load ptr, ptr [[PROTP2]], align 8
18+
; CHECK-NEXT: br label %[[EXIT]]
19+
; CHECK: [[EXIT]]:
20+
; CHECK-NEXT: [[RETVAL:%.*]] = phi ptr [ [[LOAD1]], %[[T]] ], [ [[LOAD2]], %[[F]] ]
21+
; CHECK-NEXT: ret ptr [[RETVAL]]
22+
;
23+
br i1 %sel, label %t, label %f
24+
25+
t:
26+
%protp1 = call ptr @llvm.protected.field.ptr.p0(ptr %p1, i64 1, i1 true)
27+
%load1 = load ptr, ptr %protp1
28+
br label %exit
29+
30+
f:
31+
%protp2 = call ptr @llvm.protected.field.ptr.p0(ptr %p2, i64 2, i1 true)
32+
%load2 = load ptr, ptr %protp2
33+
br label %exit
34+
35+
exit:
36+
%retval = phi ptr [ %load1, %t ], [ %load2, %f ]
37+
ret ptr %retval
38+
}

0 commit comments

Comments
 (0)