Skip to content

Commit

Permalink
Dissallow non-empty metadata for invariant.group
Browse files Browse the repository at this point in the history
Summary:
This feature is not needed, but it might be usefull in the future
to use metadata to mark what which function should support it
(and strip it when not).

Reviewers: rsmith, sanjoy, amharc, kuhar

Subscribers: hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D45419

llvm-svn: 332787
  • Loading branch information
prazek committed May 18, 2018
1 parent a26a08c commit ce35826
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 58 deletions.
11 changes: 5 additions & 6 deletions llvm/docs/LangRef.rst
Expand Up @@ -5314,10 +5314,10 @@ Irreducible loop header weights are typically based on profile data.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The experimental ``invariant.group`` metadata may be attached to
``load``/``store`` instructions.
``load``/``store`` instructions referencing a single metadata with no entries.
The existence of the ``invariant.group`` metadata on the instruction tells
the optimizer that every ``load`` and ``store`` to the same pointer operand
within the same invariant group can be assumed to load or store the same
can be assumed to load or store the same
value (but see the ``llvm.launder.invariant.group`` intrinsic which affects
when two pointers are considered the same). Pointers returned by bitcast or
getelementptr with only zero indices are considered the same.
Expand All @@ -5334,7 +5334,6 @@ Examples:

%a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
call void @foo(i8* %ptr)
%b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed

%newPtr = call i8* @getPointer(i8* %ptr)
%c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
Expand All @@ -5351,8 +5350,7 @@ Examples:
declare i8* @getPointer(i8*)
declare i8* @llvm.launder.invariant.group(i8*)

!0 = !{!"magic ptr"}
!1 = !{!"other ptr"}
!0 = !{}

The invariant.group metadata must be dropped when replacing one pointer by
another based on aliasing information. This is because invariant.group is tied
Expand Down Expand Up @@ -7637,7 +7635,8 @@ referenced by the load contains the same value at all points in the
program where the memory location is known to be dereferenceable.

The optional ``!invariant.group`` metadata must reference a single metadata name
``<index>`` corresponding to a metadata node. See ``invariant.group`` metadata.
``<index>`` corresponding to a metadata node with no entries.
See ``invariant.group`` metadata.

The optional ``!nonnull`` metadata must reference a single
metadata name ``<index>`` corresponding to a metadata node with no
Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Expand Up @@ -109,6 +109,8 @@ Changes to the LLVM IR

* invariant.group.barrier has been renamed to launder.invariant.group.

* invariant.group metadata can now refer only empty metadata nodes.

Changes to the ARM Backend
--------------------------

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
Expand Up @@ -355,8 +355,8 @@ MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
MemDepResult
MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
BasicBlock *BB) {
auto *InvariantGroupMD = LI->getMetadata(LLVMContext::MD_invariant_group);
if (!InvariantGroupMD)

if (!LI->getMetadata(LLVMContext::MD_invariant_group))
return MemDepResult::getUnknown();

// Take the ptr operand after all casts and geps 0. This way we can search
Expand Down Expand Up @@ -417,7 +417,7 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
// same pointer operand) we can assume that value pointed by pointer
// operand didn't change.
if ((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
U->getMetadata(LLVMContext::MD_invariant_group) == InvariantGroupMD)
U->getMetadata(LLVMContext::MD_invariant_group) != nullptr)
ClosestDependency = GetClosestDependency(ClosestDependency, U);
}
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
Expand Up @@ -11,7 +11,7 @@ enter:
%val = load i8, i8* @tmp, !invariant.group !0, !tbaa !{!1, !1, i64 0}
%ptr = call i8* @llvm.launder.invariant.group.p0i8(i8* @tmp)

; CHECK: store i8 42, i8* @tmp
; CHECK: store i8 42, i8* @tmp{{$}}
store i8 42, i8* %ptr, !invariant.group !0

ret void
Expand All @@ -20,5 +20,5 @@ enter:

declare i8* @llvm.launder.invariant.group.p0i8(i8*)

!0 = !{!"something"}
!0 = !{}
!1 = !{!"x", !0}
38 changes: 15 additions & 23 deletions llvm/test/Transforms/GVN/invariant.group.ll
Expand Up @@ -74,7 +74,7 @@ entry:
%2 = bitcast %struct.A* %1 to i8***

; CHECK: %vtable = load {{.*}} !invariant.group
%vtable = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable = load i8**, i8*** %2, align 8, !invariant.group !0
%cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
call void @llvm.assume(i1 %cmp.vtables)

Expand All @@ -83,29 +83,29 @@ entry:
%4 = bitcast %struct.A* %3 to void (%struct.A*)***

; CHECK: call void @_ZN1A3fooEv(
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
%vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
%5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
call void %5(%struct.A* %3)
%6 = load %struct.A*, %struct.A** %a, align 8
%7 = bitcast %struct.A* %6 to void (%struct.A*)***

; CHECK: call void @_ZN1A3fooEv(
%vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !2
%vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
%vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
%8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8

call void %8(%struct.A* %6)
%9 = load %struct.A*, %struct.A** %a, align 8
%10 = bitcast %struct.A* %9 to void (%struct.A*)***

%vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !2
%vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
%vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
%11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
; CHECK: call void @_ZN1A3fooEv(
call void %11(%struct.A* %9)

%vtable5 = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
%vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
%12 = bitcast i8** %vfn6 to void (%struct.A*)**
%13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
Expand All @@ -127,15 +127,15 @@ entry:
%2 = bitcast %struct.A* %1 to i8***

; CHECK: %vtable = load {{.*}} !invariant.group
%vtable = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable = load i8**, i8*** %2, align 8, !invariant.group !0
%cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)

store %struct.A* %1, %struct.A** %a, align 8
; CHECK-NOT: !invariant.group
%3 = load %struct.A*, %struct.A** %a, align 8
%4 = bitcast %struct.A* %3 to void (%struct.A*)***

%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
%vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
%5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
call void %5(%struct.A* %3)
Expand All @@ -152,7 +152,7 @@ enter:
; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
%a = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%b = load i8, i8* %ptr, !invariant.group !1
%b = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[A]])
call void @bar(i8 %a)
; CHECK: call void @bar(i8 %[[A]])
Expand All @@ -169,7 +169,7 @@ enter:
; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
%c = load i8, i8* %ptr
; CHECK-NOT: load
%d = load i8, i8* %ptr, !invariant.group !1
%d = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[D]])
call void @bar(i8 %c)
; CHECK: call void @bar(i8 %[[D]])
Expand All @@ -184,7 +184,7 @@ enter:
store i8 42, i8* %ptr
call void @foo(i8* %ptr)
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
%e = load i8, i8* %ptr, !invariant.group !1
%e = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%f = load i8, i8* %ptr
; CHECK: call void @bar(i8 %[[E]])
Expand All @@ -200,10 +200,10 @@ enter:
%ptr = alloca i8
store i8 42, i8* %ptr
call void @foo(i8* %ptr)
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group ![[OneMD:[0-9]]]
%e = load i8, i8* %ptr, !invariant.group !1
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
%e = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%f = load i8, i8* %ptr, !invariant.group !1
%f = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %e)
; CHECK: call void @bar(i8 %[[E]])
Expand Down Expand Up @@ -298,12 +298,7 @@ entry:
%a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
; CHECK: call void @bar(i8 42)
call void @bar(i8 %a)

call void @foo(i8* %ptr)
%b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed
; CHECK: call void @bar(i8 %b)
call void @bar(i8 %b)


%newPtr = call i8* @getPointer(i8* %ptr)
%c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
; CHECK: call void @bar(i8 %c)
Expand Down Expand Up @@ -448,7 +443,4 @@ declare void @llvm.assume(i1 %cmp.vtables) #0


attributes #0 = { nounwind }
; CHECK: ![[OneMD]] = !{!"other ptr"}
!0 = !{!"magic ptr"}
!1 = !{!"other ptr"}
!2 = !{!"vtable_of_a"}
!0 = !{}
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
Expand Up @@ -76,4 +76,4 @@ declare void @changeTmp3ValAndCallBarrierInside()

declare i8* @llvm.launder.invariant.group(i8*)

!0 = !{!"something"}
!0 = !{}
39 changes: 16 additions & 23 deletions llvm/test/Transforms/NewGVN/invariant.group.ll
Expand Up @@ -75,7 +75,7 @@ entry:
%2 = bitcast %struct.A* %1 to i8***

; CHECK: %vtable = load {{.*}} !invariant.group
%vtable = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable = load i8**, i8*** %2, align 8, !invariant.group !0
%cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
call void @llvm.assume(i1 %cmp.vtables)

Expand All @@ -84,29 +84,29 @@ entry:
%4 = bitcast %struct.A* %3 to void (%struct.A*)***

; CHECK: call void @_ZN1A3fooEv(
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
%vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
%5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
call void %5(%struct.A* %3)
%6 = load %struct.A*, %struct.A** %a, align 8
%7 = bitcast %struct.A* %6 to void (%struct.A*)***

; CHECK: call void @_ZN1A3fooEv(
%vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !2
%vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
%vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
%8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8

call void %8(%struct.A* %6)
%9 = load %struct.A*, %struct.A** %a, align 8
%10 = bitcast %struct.A* %9 to void (%struct.A*)***

%vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !2
%vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
%vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
%11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
; CHECK: call void @_ZN1A3fooEv(
call void %11(%struct.A* %9)

%vtable5 = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
%vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
%12 = bitcast i8** %vfn6 to void (%struct.A*)**
%13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
Expand All @@ -128,15 +128,15 @@ entry:
%2 = bitcast %struct.A* %1 to i8***

; CHECK: %vtable = load {{.*}} !invariant.group
%vtable = load i8**, i8*** %2, align 8, !invariant.group !2
%vtable = load i8**, i8*** %2, align 8, !invariant.group !0
%cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)

store %struct.A* %1, %struct.A** %a, align 8
; CHECK-NOT: !invariant.group
%3 = load %struct.A*, %struct.A** %a, align 8
%4 = bitcast %struct.A* %3 to void (%struct.A*)***

%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
%vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
%vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
%5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
call void %5(%struct.A* %3)
Expand All @@ -153,7 +153,7 @@ enter:
; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
%a = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%b = load i8, i8* %ptr, !invariant.group !1
%b = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[A]])
call void @bar(i8 %a)
; CHECK: call void @bar(i8 %[[A]])
Expand All @@ -170,7 +170,7 @@ enter:
; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
%c = load i8, i8* %ptr
; CHECK-NOT: load
%d = load i8, i8* %ptr, !invariant.group !1
%d = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[D]])
call void @bar(i8 %c)
; CHECK: call void @bar(i8 %[[D]])
Expand All @@ -185,7 +185,7 @@ enter:
store i8 42, i8* %ptr
call void @foo(i8* %ptr)
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
%e = load i8, i8* %ptr, !invariant.group !1
%e = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%f = load i8, i8* %ptr
; CHECK: call void @bar(i8 %[[E]])
Expand All @@ -201,10 +201,10 @@ enter:
%ptr = alloca i8
store i8 42, i8* %ptr
call void @foo(i8* %ptr)
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group ![[OneMD:[0-9]]]
%e = load i8, i8* %ptr, !invariant.group !1
; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
%e = load i8, i8* %ptr, !invariant.group !0
; CHECK-NOT: load
%f = load i8, i8* %ptr, !invariant.group !1
%f = load i8, i8* %ptr, !invariant.group !0
; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %e)
; CHECK: call void @bar(i8 %[[E]])
Expand Down Expand Up @@ -244,6 +244,7 @@ entry:
%ptr = alloca i8
store i8 42, i8* %ptr, !invariant.group !0
%ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
; CHECK-NOT: load
%a = load i8, i8* %ptr2, !invariant.group !0

; CHECK: ret i8 42
Expand Down Expand Up @@ -298,12 +299,7 @@ entry:
%a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
; CHECK: call void @bar(i8 42)
call void @bar(i8 %a)

call void @foo(i8* %ptr)
%b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed
; CHECK: call void @bar(i8 %b)
call void @bar(i8 %b)


%newPtr = call i8* @getPointer(i8* %ptr)
%c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
; CHECK: call void @bar(i8 %c)
Expand Down Expand Up @@ -448,7 +444,4 @@ declare void @llvm.assume(i1 %cmp.vtables) #0


attributes #0 = { nounwind }
; CHECK: ![[OneMD]] = !{!"other ptr"}
!0 = !{!"magic ptr"}
!1 = !{!"other ptr"}
!2 = !{!"vtable_of_a"}
!0 = !{}

0 comments on commit ce35826

Please sign in to comment.