diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 3bc535595730..6033707ff0b2 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2965,6 +2965,12 @@ bool GVNPass::performScalarPRE(Instruction *CurInst) { return false; } + // Protected pointer field loads/stores should be paired with the intrinsic + // to avoid unnecessary address escapes. + if (auto *II = dyn_cast(CurInst)) + if (II->getIntrinsicID() == Intrinsic::protected_field_ptr) + return false; + uint32_t ValNo = VN.lookup(CurInst); // Look for the predecessors for PRE opportunities. We're diff --git a/llvm/test/Transforms/GVN/PRE/protected-field-ptr.ll b/llvm/test/Transforms/GVN/PRE/protected-field-ptr.ll new file mode 100644 index 000000000000..c045242e4eac --- /dev/null +++ b/llvm/test/Transforms/GVN/PRE/protected-field-ptr.ll @@ -0,0 +1,41 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=gvn -S < %s | FileCheck %s + +; Check that PRE is inhibited for llvm.protected.field.ptr. +declare void @use(ptr) + +define void @test1(i1 %c, ptr %arg) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[DOTBB2_CRIT_EDGE:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[CALL:%.*]] = call ptr @llvm.protected.field.ptr.p0(ptr [[ARG:%.*]], i64 1, i1 true) +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[CALL2:%.*]] = call ptr @llvm.protected.field.ptr.p0(ptr [[ARG]], i64 1, i1 true) +; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[CALL2]], align 8 +; CHECK-NEXT: call void @use(ptr [[V]]) +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[CALL3:%.*]] = call ptr @llvm.protected.field.ptr.p0(ptr [[ARG]], i64 1, i1 true) +; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[CALL3]], align 8 +; CHECK-NEXT: call void @use(ptr [[V2]]) +; CHECK-NEXT: br label [[DOTBB2_CRIT_EDGE]] +; + br i1 %c, label %bb1, label %bb2 + +bb1: + %call = call ptr @llvm.protected.field.ptr.p0(ptr %arg, i64 1, i1 true) + br label %bb3 + +bb2: + %call2 = call ptr @llvm.protected.field.ptr.p0(ptr %arg, i64 1, i1 true) + %v = load ptr, ptr %call2 + call void @use(ptr %v) + br label %bb3 + +bb3: + %call3 = call ptr @llvm.protected.field.ptr.p0(ptr %arg, i64 1, i1 true) + %v2 = load ptr, ptr %call3 + call void @use(ptr %v2) + br label %bb2 +}