Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -5314,10 +5314,10 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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. @@ -5334,7 +5334,6 @@ %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 @@ -5351,8 +5350,7 @@ 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 @@ -7637,7 +7635,8 @@ program where the memory location is known to be dereferenceable. The optional ``!invariant.group`` metadata must reference a single metadata name - ```` corresponding to a metadata node. See ``invariant.group`` metadata. + ```` corresponding to a metadata node with no entries. + See ``invariant.group`` metadata. The optional ``!nonnull`` metadata must reference a single metadata name ```` corresponding to a metadata node with no Index: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -82,6 +82,8 @@ * 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 -------------------------- Index: llvm/lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -355,8 +355,8 @@ 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 @@ -417,7 +417,7 @@ // same pointer operand) we can assume that value pointed by pointer // operand didn't change. if ((isa(U) || isa(U)) && - U->getMetadata(LLVMContext::MD_invariant_group) == InvariantGroupMD) + U->getMetadata(LLVMContext::MD_invariant_group) != nullptr) ClosestDependency = GetClosestDependency(ClosestDependency, U); } } Index: llvm/test/Transforms/CodeGenPrepare/invariant.group.ll =================================================================== --- llvm/test/Transforms/CodeGenPrepare/invariant.group.ll +++ llvm/test/Transforms/CodeGenPrepare/invariant.group.ll @@ -11,7 +11,7 @@ %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 @@ -20,5 +20,5 @@ declare i8* @llvm.launder.invariant.group.p0i8(i8*) -!0 = !{!"something"} +!0 = !{} !1 = !{!"x", !0} Index: llvm/test/Transforms/GVN/invariant.group.ll =================================================================== --- llvm/test/Transforms/GVN/invariant.group.ll +++ llvm/test/Transforms/GVN/invariant.group.ll @@ -74,7 +74,7 @@ %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) @@ -83,7 +83,7 @@ %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) @@ -91,7 +91,7 @@ %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 @@ -99,13 +99,13 @@ %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 @@ -127,7 +127,7 @@ %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 @@ -135,7 +135,7 @@ %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) @@ -152,7 +152,7 @@ ; 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]]) @@ -169,7 +169,7 @@ ; 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]]) @@ -184,7 +184,7 @@ 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]]) @@ -200,10 +200,10 @@ %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]]) @@ -298,12 +298,7 @@ %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) @@ -448,7 +443,4 @@ attributes #0 = { nounwind } -; CHECK: ![[OneMD]] = !{!"other ptr"} -!0 = !{!"magic ptr"} -!1 = !{!"other ptr"} -!2 = !{!"vtable_of_a"} +!0 = !{} \ No newline at end of file Index: llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll =================================================================== --- llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll @@ -76,4 +76,4 @@ declare i8* @llvm.launder.invariant.group(i8*) -!0 = !{!"something"} +!0 = !{} Index: llvm/test/Transforms/NewGVN/invariant.group.ll =================================================================== --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -75,7 +75,7 @@ %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) @@ -84,7 +84,7 @@ %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) @@ -92,7 +92,7 @@ %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 @@ -100,13 +100,13 @@ %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 @@ -128,7 +128,7 @@ %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 @@ -136,7 +136,7 @@ %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) @@ -153,7 +153,7 @@ ; 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]]) @@ -170,7 +170,7 @@ ; 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]]) @@ -185,7 +185,7 @@ 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]]) @@ -201,10 +201,10 @@ %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]]) @@ -244,6 +244,7 @@ %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 @@ -298,12 +299,7 @@ %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) @@ -448,7 +444,4 @@ attributes #0 = { nounwind } -; CHECK: ![[OneMD]] = !{!"other ptr"} -!0 = !{!"magic ptr"} -!1 = !{!"other ptr"} -!2 = !{!"vtable_of_a"} +!0 = !{} \ No newline at end of file