Rename invariant.group.barrier to launder.invariant.group
authorPiotr Padlewski <piotr.padlewski@gmail.com>
Thu, 3 May 2018 11:03:01 +0000 (11:03 +0000)
committerPiotr Padlewski <piotr.padlewski@gmail.com>
Thu, 3 May 2018 11:03:01 +0000 (11:03 +0000)
Summary:
This is one of the initial commit of "RFC: Devirtualization v2" proposal:
https://docs.google.com/document/d/16GVtCpzK8sIHNc2qZz6RN8amICNBtvjWUod2SujZVEo/edit?usp=sharing

Reviewers: rsmith, amharc, kuhar, sanjoy

Subscribers: arsenm, nhaehnle, javed.absar, hiraditya, llvm-commits

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

llvm-svn: 331448

29 files changed:
clang/lib/CodeGen/CGClass.cpp
clang/lib/CodeGen/CGExpr.cpp
clang/lib/CodeGen/CGExprCXX.cpp
clang/test/CodeGenCXX/invariant.group-for-vptrs.cpp
clang/test/CodeGenCXX/strict-vtable-pointers.cpp
llvm/docs/LangRef.rst
llvm/docs/ReleaseNotes.rst
llvm/include/llvm/IR/IRBuilder.h
llvm/include/llvm/IR/Intrinsics.td
llvm/include/llvm/IR/Value.h
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/lib/Analysis/MemorySSA.cpp
llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/IR/AutoUpgrade.cpp
llvm/lib/IR/Value.cpp
llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
llvm/test/Analysis/MemorySSA/invariant-groups.ll
llvm/test/Bitcode/upgrade-invariant-group-barrier.ll [new file with mode: 0644]
llvm/test/CodeGen/AArch64/GlobalISel/unknown-intrinsic.ll
llvm/test/CodeGen/AMDGPU/promote-alloca-invariant-markers.ll
llvm/test/CodeGen/Generic/intrinsics.ll
llvm/test/Other/Inputs/invariant.group.barrier.ll [deleted file]
llvm/test/Other/launder.invariant.group.ll [moved from llvm/test/Other/invariant.group.barrier.ll with 59% similarity]
llvm/test/Transforms/CodeGenPrepare/invariant.group.ll
llvm/test/Transforms/GVN/invariant.group.ll
llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll
llvm/test/Transforms/NewGVN/invariant.group.ll

index fb09b4d..3b142d7 100644 (file)
@@ -1276,7 +1276,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
     if (CGM.getCodeGenOpts().StrictVTablePointers &&
         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
         isInitializerOfDynamicClass(*B))
-      CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+      CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
     EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
   }
 
@@ -1293,7 +1293,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
     if (CGM.getCodeGenOpts().StrictVTablePointers &&
         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
         isInitializerOfDynamicClass(*B))
-      CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+      CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
     EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
   }
 
@@ -1477,11 +1477,11 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
 
     // Initialize the vtable pointers before entering the body.
     if (!CanSkipVTablePointerInitialization(*this, Dtor)) {
-      // Insert the llvm.invariant.group.barrier intrinsic before initializing
+      // Insert the llvm.launder.invariant.group intrinsic before initializing
       // the vptrs to cancel any previous assumptions we might have made.
       if (CGM.getCodeGenOpts().StrictVTablePointers &&
           CGM.getCodeGenOpts().OptimizationLevel > 0)
-        CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+        CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
       InitializeVTablePointers(Dtor->getParent());
     }
 
index 55b67db..7b0f253 100644 (file)
@@ -3850,7 +3850,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
         hasAnyVptr(FieldType, getContext()))
       // Because unions can easily skip invariant.barriers, we need to add
       // a barrier every time CXXRecord field with vptr is referenced.
-      addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),
+      addr = Address(Builder.CreateLaunderInvariantGroup(addr.getPointer()),
                      addr.getAlignment());
   } else {
     // For structs, we GEP to the field that the record layout suggests.
index 914dd18..8955d8a 100644 (file)
@@ -1696,13 +1696,13 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
   llvm::Type *elementTy = ConvertTypeForMem(allocType);
   Address result = Builder.CreateElementBitCast(allocation, elementTy);
 
-  // Passing pointer through invariant.group.barrier to avoid propagation of
+  // Passing pointer through launder.invariant.group to avoid propagation of
   // vptrs information which may be included in previous type.
   // To not break LTO with different optimizations levels, we do it regardless
   // of optimization level.
   if (CGM.getCodeGenOpts().StrictVTablePointers &&
       allocator->isReservedGlobalPlacementOperator())
-    result = Address(Builder.CreateInvariantGroupBarrier(result.getPointer()),
+    result = Address(Builder.CreateLaunderInvariantGroup(result.getPointer()),
                      result.getAlignment());
 
   EmitNewInitializer(*this, E, allocType, elementTy, result, numElements,
index 45671e5..d4f80dd 100644 (file)
@@ -56,7 +56,7 @@ void testInternallyVisible(bool p) {
 
 // Checking D::D()
 // CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
-// CHECK:  = call i8* @llvm.invariant.group.barrier.p0i8(i8*
+// CHECK:  = call i8* @llvm.launder.invariant.group.p0i8(i8*
 // CHECK:  call void @_ZN1AC2Ev(%struct.A*
 // CHECK: store {{.*}} !invariant.group ![[MD]]
 
index c45e7a6..f92cd05 100644 (file)
@@ -53,7 +53,7 @@ struct DynamicFrom2Virtuals :
 };
 
 // CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
+// CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW-LABEL: {{^}}}
 void LocalObjects() {
   DynamicBase1 DB;
@@ -81,20 +81,20 @@ void LocalObjects() {
 
 struct DynamicFromVirtualStatic1;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN25DynamicFromVirtualStatic1C1Ev
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
 struct DynamicFrom2Virtuals;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN20DynamicFrom2VirtualsC1Ev
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
 
 // CHECK-NEW-LABEL: define void @_Z9Pointers1v()
-// CHECK-NEW-NOT: @llvm.invariant.group.barrier.p0i8(
+// CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
 
-// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS2:.*]])
+// CHECK-NEW: %[[THIS3:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS2:.*]])
 // CHECK-NEW: %[[THIS4:.*]] = bitcast i8* %[[THIS3]] to %[[DynamicDerived:.*]]*
 // CHECK-NEW: call void @_ZN14DynamicDerivedC1Ev(%[[DynamicDerived:.*]]* %[[THIS4]])
 // CHECK-NEW-LABEL: {{^}}}
@@ -109,9 +109,9 @@ void Pointers1() {
 
 // CHECK-NEW-LABEL: define void @_Z14HackingObjectsv()
 // CHECK-NEW:  call void @_ZN12DynamicBase1C1Ev
-// CHECK-NEW:  call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-NEW:  call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW:  call void @_ZN14DynamicDerivedC1Ev(
-// CHECK-NEW:  call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-NEW:  call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW: call void @_ZN12DynamicBase1C1Ev(
 // CHECK-NEW-LABEL: {{^}}}
 void HackingObjects() {
@@ -131,7 +131,7 @@ void HackingObjects() {
 /*** Testing Constructors ***/
 struct DynamicBase1;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1C2Ev(
-// CHECK-CTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
 
@@ -140,7 +140,7 @@ struct DynamicDerived;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
 // CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}}
 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1:.*]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1:.*]])
 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]*
 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %[[THIS3]] to %[[DynamicBase:.*]]*
 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]])
@@ -154,15 +154,15 @@ struct DynamicDerivedMultiple;
 
 // CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}}
 // CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8*
-// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier.p0i8(i8* %[[THIS1]])
+// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* %[[THIS1]])
 // CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]*
 // CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]*
 // CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]])
 
-// CHECK-CTORS: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
 
 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8
 
 
 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
@@ -177,7 +177,7 @@ struct DynamicDerivedMultiple;
 
 struct DynamicFromStatic;
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticC2Ev(
-// CHECK-CTORS-NOT: @llvm.invariant.group.barrier.p0i8(
+// CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
 struct A {
@@ -206,15 +206,15 @@ void g2(A *a) {
 void UnionsBarriers(U *u) {
   // CHECK-NEW: call void @_Z9changeToBP1U(
   changeToB(u);
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z2g2P1A(%struct.A*
   g2(&u->b);
   // CHECK-NEW: call void @_Z9changeToAP1U(%union.U* 
   changeToA(u);
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // call void @_Z2g2P1A(%struct.A* %a)
   g2(&u->a);
-  // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
 }
 
 struct HoldingVirtuals {
@@ -233,10 +233,10 @@ void take(AnotherEmpty &);
 
 // CHECK-NEW-LABEL: noBarriers
 void noBarriers(NoVptrs &noVptrs) {
-  // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: 42
   noVptrs.a += 42;
-  // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z4takeR12AnotherEmpty(
   take(noVptrs.empty);
 }
@@ -249,10 +249,10 @@ void take(HoldingVirtuals &);
 
 // CHECK-NEW-LABEL: define void @_Z15UnionsBarriers2R2U2
 void UnionsBarriers2(U2 &u) {
-  // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: 42
   u.z += 42;
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z4takeR15HoldingVirtuals(
   take(u.h);
 }
@@ -279,24 +279,24 @@ void take(VirtualInVBase &);
 void take(VirtualInheritance &);
 
 void UnionsBarrier3(U3 &u) {
-  // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW-NOT: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: 42
   u.z += 42;
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
   take(u.v1);
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z4takeR13VirtualInBase(
   take(u.v2);
 
-  // CHECK-NEW: call i8* @llvm.invariant.group.barrier.p0i8(i8*
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z4takeR18VirtualInheritance(
   take(u.v3);
 }
 
 /** DTORS **/
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-DTORS-LABEL: {{^}}}
 
 
@@ -305,22 +305,22 @@ void UnionsBarrier3(U3 &u) {
 // CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN17DynamicFromStaticD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-DTORS-LABEL: {{^}}}
 
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleD2Ev(
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase2D2Ev(
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN12DynamicBase1D2Ev
-// CHECK-DTORS: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-DTORS: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-DTORS-LABEL: {{^}}}
 
 // CHECK-DTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedD2Ev
-// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier.p0i8(
+// CHECK-DTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-DTORS-LABEL: {{^}}}
 
 
index 963a66f..ba13d8e 100644 (file)
@@ -5318,7 +5318,7 @@ The experimental ``invariant.group`` metadata may be attached to
 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
-value (but see the ``llvm.invariant.group.barrier`` intrinsic which affects
+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.
 
@@ -5343,13 +5343,13 @@ Examples:
    store i8 %unknownValue, i8* %ptr, !invariant.group !0 ; Can assume that %unknownValue == 42
 
    call void @foo(i8* %ptr)
-   %newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
-   %d = load i8, i8* %newPtr2, !invariant.group !0  ; Can't step through invariant.group.barrier to get value of %ptr
+   %newPtr2 = call i8* @llvm.launder.invariant.group(i8* %ptr)
+   %d = load i8, i8* %newPtr2, !invariant.group !0  ; Can't step through launder.invariant.group to get value of %ptr
 
    ...
    declare void @foo(i8*)
    declare i8* @getPointer(i8*)
-   declare i8* @llvm.invariant.group.barrier(i8*)
+   declare i8* @llvm.launder.invariant.group(i8*)
 
    !0 = !{!"magic ptr"}
    !1 = !{!"other ptr"}
@@ -12908,7 +12908,7 @@ Semantics:
 
 This intrinsic indicates that the memory is mutable again.
 
-'``llvm.invariant.group.barrier``' Intrinsic
+'``llvm.launder.invariant.group``' Intrinsic
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Syntax:
@@ -12919,12 +12919,12 @@ argument.
 
 ::
 
-      declare i8* @llvm.invariant.group.barrier.p0i8(i8* <ptr>)
+      declare i8* @llvm.launder.invariant.group.p0i8(i8* <ptr>)
 
 Overview:
 """""""""
 
-The '``llvm.invariant.group.barrier``' intrinsic can be used when an invariant
+The '``llvm.launder.invariant.group``' intrinsic can be used when an invariant
 established by invariant.group metadata no longer holds, to obtain a new pointer
 value that does not carry the invariant information. It is an experimental
 intrinsic, which means that its semantics might change in the future.
@@ -12933,7 +12933,7 @@ intrinsic, which means that its semantics might change in the future.
 Arguments:
 """"""""""
 
-The ``llvm.invariant.group.barrier`` takes only one argument, which is
+The ``llvm.launder.invariant.group`` takes only one argument, which is
 the pointer to the memory for which the ``invariant.group`` no longer holds.
 
 Semantics:
@@ -12941,6 +12941,7 @@ Semantics:
 
 Returns another pointer that aliases its argument but which is considered different
 for the purposes of ``load``/``store`` ``invariant.group`` metadata.
+It does not read any accessible memory and the execution can be speculated.
 
 .. _constrainedfp:
 
index be23551..b8da194 100644 (file)
@@ -107,6 +107,8 @@ Changes to the LLVM IR
   have changed. Alignment is no longer an argument, and are instead conveyed as
   parameter attributes.
 
+* invariant.group.barrier has been renamed to launder.invariant.group.
+
 Changes to the ARM Backend
 --------------------------
 
index cc37c3a..ce1ecde 100644 (file)
@@ -1962,28 +1962,26 @@ public:
                            Name);
   }
 
-  /// Create an invariant.group.barrier intrinsic call, that stops
-  /// optimizer to propagate equality using invariant.group metadata.
-  /// If Ptr type is different from pointer to i8, it's casted to pointer to i8
-  /// in the same address space before call and casted back to Ptr type after
-  /// call.
-  Value *CreateInvariantGroupBarrier(Value *Ptr) {
+  /// Create a launder.invariant.group intrinsic call. If Ptr type is
+  /// different from pointer to i8, it's casted to pointer to i8 in the same
+  /// address space before call and casted back to Ptr type after call.
+  Value *CreateLaunderInvariantGroup(Value *Ptr) {
     assert(isa<PointerType>(Ptr->getType()) &&
-           "invariant.group.barrier only applies to pointers.");
+           "launder.invariant.group only applies to pointers.");
     auto *PtrType = Ptr->getType();
     auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
     if (PtrType != Int8PtrTy)
       Ptr = CreateBitCast(Ptr, Int8PtrTy);
     Module *M = BB->getParent()->getParent();
-    Function *FnInvariantGroupBarrier = Intrinsic::getDeclaration(
-        M, Intrinsic::invariant_group_barrier, {Int8PtrTy});
+    Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration(
+        M, Intrinsic::launder_invariant_group, {Int8PtrTy});
 
-    assert(FnInvariantGroupBarrier->getReturnType() == Int8PtrTy &&
-           FnInvariantGroupBarrier->getFunctionType()->getParamType(0) ==
+    assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&
+           FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==
                Int8PtrTy &&
-           "InvariantGroupBarrier should take and return the same type");
+           "LaunderInvariantGroup should take and return the same type");
 
-    CallInst *Fn = CreateCall(FnInvariantGroupBarrier, {Ptr});
+    CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr});
 
     if (PtrType != Int8PtrTy)
       return CreateBitCast(Fn, PtrType);
index b98f587..aa4c6dc 100644 (file)
@@ -710,7 +710,7 @@ def int_invariant_end   : Intrinsic<[],
                                      llvm_anyptr_ty],
                                     [IntrArgMemOnly, NoCapture<2>]>;
 
-// invariant.group.barrier can't be marked with 'readnone' (IntrNoMem),
+// launder.invariant.group can't be marked with 'readnone' (IntrNoMem),
 // because it would cause CSE of two barriers with the same argument.
 // Inaccessiblememonly says that the barrier doesn't read the argument,
 // but it changes state not accessible to this module. This way
@@ -722,9 +722,9 @@ def int_invariant_end   : Intrinsic<[],
 // it would remove barrier.
 // Note that it is still experimental, which means that its semantics
 // might change in the future.
-def int_invariant_group_barrier : Intrinsic<[llvm_anyptr_ty],
+def int_launder_invariant_group : Intrinsic<[llvm_anyptr_ty],
                                             [LLVMMatchType<0>],
-                                            [IntrInaccessibleMemOnly]>;
+                                            [IntrInaccessibleMemOnly, IntrSpeculatable]>;
 
 //===------------------------ Stackmap Intrinsics -------------------------===//
 //
index 99ab5f2..683775c 100644 (file)
@@ -509,15 +509,16 @@ public:
                          static_cast<const Value *>(this)->stripPointerCasts());
   }
 
-  /// Strip off pointer casts, all-zero GEPs, aliases and barriers.
+  /// Strip off pointer casts, all-zero GEPs, aliases and invariant group
+  /// info.
   ///
   /// Returns the original uncasted value.  If this is called on a non-pointer
   /// value, it returns 'this'. This function should be used only in
   /// Alias analysis.
-  const Value *stripPointerCastsAndBarriers() const;
-  Value *stripPointerCastsAndBarriers() {
+  const Value *stripPointerCastsAndInvariantGroups() const;
+  Value *stripPointerCastsAndInvariantGroups() {
     return const_cast<Value *>(
-        static_cast<const Value *>(this)->stripPointerCastsAndBarriers());
+        static_cast<const Value *>(this)->stripPointerCastsAndInvariantGroups());
   }
 
   /// Strip off pointer casts and all-zero GEPs.
index 0793d01..aaa79bc 100644 (file)
@@ -985,8 +985,8 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
                                             const GEPOperator *GEP2,
                                             uint64_t V2Size,
                                             const DataLayout &DL) {
-  assert(GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
-             GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
+  assert(GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() ==
+             GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() &&
          GEP1->getPointerOperandType() == GEP2->getPointerOperandType() &&
          "Expected GEPs with the same pointer operand");
 
@@ -1264,8 +1264,8 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
     // If we know the two GEPs are based off of the exact same pointer (and not
     // just the same underlying object), see if that tells us anything about
     // the resulting pointers.
-    if (GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
-            GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
+    if (GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() ==
+            GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() &&
         GEP1->getPointerOperandType() == GEP2->getPointerOperandType()) {
       AliasResult R = aliasSameBasePointerGEPs(GEP1, V1Size, GEP2, V2Size, DL);
       // If we couldn't find anything interesting, don't abandon just yet.
@@ -1578,8 +1578,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size,
     return NoAlias;
 
   // Strip off any casts if they exist.
-  V1 = V1->stripPointerCastsAndBarriers();
-  V2 = V2->stripPointerCastsAndBarriers();
+  V1 = V1->stripPointerCastsAndInvariantGroups();
+  V2 = V2->stripPointerCastsAndInvariantGroups();
 
   // If V1 or V2 is undef, the result is NoAlias because we can always pick a
   // value for undef that aliases nothing in the program.
index 7341188..661922d 100644 (file)
@@ -352,9 +352,6 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysis &AA,
                                                    const Instruction *I) {
   // If the memory can't be changed, then loads of the memory can't be
   // clobbered.
-  //
-  // FIXME: We should handle invariant groups, as well. It's a bit harder,
-  // because we need to pay close attention to invariant group barriers.
   return isa<LoadInst>(I) && (I->getMetadata(LLVMContext::MD_invariant_load) ||
                               AA.pointsToConstantMemory(cast<LoadInst>(I)->
                                                           getPointerOperand()));
index 8729db4..3e8fd4e 100644 (file)
@@ -1668,7 +1668,7 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
       InsertedInsts.insert(ExtVal);
       return true;
     }
-    case Intrinsic::invariant_group_barrier:
+    case Intrinsic::launder_invariant_group:
       II->replaceAllUsesWith(II->getArgOperand(0));
       II->eraseFromParent();
       return true;
index 571fd66..166e7b1 100644 (file)
@@ -1444,7 +1444,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
     updateValueMap(II, ResultReg);
     return true;
   }
-  case Intrinsic::invariant_group_barrier:
+  case Intrinsic::launder_invariant_group:
   case Intrinsic::expect: {
     unsigned ResultReg = getRegForValue(II->getArgOperand(0));
     if (!ResultReg)
index 2ac4d3a..58d323a 100644 (file)
@@ -5710,7 +5710,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
   }
   case Intrinsic::annotation:
   case Intrinsic::ptr_annotation:
-  case Intrinsic::invariant_group_barrier:
+  case Intrinsic::launder_invariant_group:
     // Drop the intrinsic, but forward the value
     setValue(&I, getValue(I.getOperand(0)));
     return nullptr;
index 13fb278..fd403f3 100644 (file)
@@ -528,6 +528,17 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
         return true;
       }
     }
+    if (Name.startswith("invariant.group.barrier")) {
+      // Rename invariant.group.barrier to launder.invariant.group
+      auto Args = F->getFunctionType()->params();
+      Type* ObjectPtr[1] = {Args[0]};
+      rename(F);
+      NewFn = Intrinsic::getDeclaration(F->getParent(),
+          Intrinsic::launder_invariant_group, ObjectPtr);
+      return true;
+
+    }
+
     break;
   }
   case 'm': {
index a479d04..2f95e93 100644 (file)
@@ -499,7 +499,7 @@ namespace {
 enum PointerStripKind {
   PSK_ZeroIndices,
   PSK_ZeroIndicesAndAliases,
-  PSK_ZeroIndicesAndAliasesAndBarriers,
+  PSK_ZeroIndicesAndAliasesAndInvariantGroups,
   PSK_InBoundsConstantIndices,
   PSK_InBounds
 };
@@ -518,7 +518,7 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
     if (auto *GEP = dyn_cast<GEPOperator>(V)) {
       switch (StripKind) {
       case PSK_ZeroIndicesAndAliases:
-      case PSK_ZeroIndicesAndAliasesAndBarriers:
+      case PSK_ZeroIndicesAndAliasesAndInvariantGroups:
       case PSK_ZeroIndices:
         if (!GEP->hasAllZeroIndices())
           return V;
@@ -546,11 +546,11 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
           V = RV;
           continue;
         }
-        // The result of invariant.group.barrier must alias it's argument,
+        // The result of launder.invariant.group must alias it's argument,
         // but it can't be marked with returned attribute, that's why it needs
         // special case.
-        if (StripKind == PSK_ZeroIndicesAndAliasesAndBarriers &&
-            CS.getIntrinsicID() == Intrinsic::invariant_group_barrier) {
+        if (StripKind == PSK_ZeroIndicesAndAliasesAndInvariantGroups &&
+            CS.getIntrinsicID() == Intrinsic::launder_invariant_group) {
           V = CS.getArgOperand(0);
           continue;
         }
@@ -576,8 +576,8 @@ const Value *Value::stripInBoundsConstantOffsets() const {
   return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this);
 }
 
-const Value *Value::stripPointerCastsAndBarriers() const {
-  return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliasesAndBarriers>(
+const Value *Value::stripPointerCastsAndInvariantGroups() const {
+  return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliasesAndInvariantGroups>(
       this);
 }
 
index cf8469f..336467a 100644 (file)
@@ -454,7 +454,7 @@ static bool isCallPromotable(CallInst *CI) {
   case Intrinsic::lifetime_end:
   case Intrinsic::invariant_start:
   case Intrinsic::invariant_end:
-  case Intrinsic::invariant_group_barrier:
+  case Intrinsic::launder_invariant_group:
   case Intrinsic::objectsize:
     return true;
   default:
@@ -878,7 +878,7 @@ bool AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I, bool SufficientLDS) {
     }
     case Intrinsic::invariant_start:
     case Intrinsic::invariant_end:
-    case Intrinsic::invariant_group_barrier:
+    case Intrinsic::launder_invariant_group:
       Intr->eraseFromParent();
       // FIXME: I think the invariant marker should still theoretically apply,
       // but the intrinsics need to be changed to accept pointers with any
index 062b574..a2535d5 100644 (file)
@@ -1,7 +1,7 @@
 ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
 ;
 ; Currently, MemorySSA doesn't support invariant groups. So, we should ignore
-; invariant.group.barrier intrinsics entirely. We'll need to pay attention to
+; launder.invariant.group intrinsics entirely. We'll need to pay attention to
 ; them when/if we decide to support invariant groups.
 
 @g = external global i32
@@ -17,8 +17,8 @@ define i32 @foo(i32* %a) {
 
   %1 = bitcast i32* %a to i8*
 ; CHECK:  3 = MemoryDef(2)
-; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
-  %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
+; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
+  %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
   %a32 = bitcast i8* %a8 to i32*
 
 ; This have to be MemoryUse(2), because we can't skip the barrier based on
@@ -36,8 +36,8 @@ define i32 @skipBarrier(i32* %a) {
 
   %1 = bitcast i32* %a to i8*
 ; CHECK: 2 = MemoryDef(1)
-; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
-  %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)  
+; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
+  %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)  
   %a32 = bitcast i8* %a8 to i32*
 
 ; We can skip the barrier only if the "skip" is not based on !invariant.group.
@@ -55,8 +55,8 @@ define i32 @skipBarrier2(i32* %a) {
 
   %1 = bitcast i32* %a to i8*
 ; CHECK: 1 = MemoryDef(liveOnEntry)
-; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
-  %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
+; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
+  %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
   %a32 = bitcast i8* %a8 to i32*
 
 ; We can skip the barrier only if the "skip" is not based on !invariant.group.
@@ -86,8 +86,8 @@ define i32 @handleInvariantGroups(i32* %a) {
   store i32 1, i32* @g, align 4
   %1 = bitcast i32* %a to i8*
 ; CHECK: 3 = MemoryDef(2)
-; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
-  %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
+; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
+  %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
   %a32 = bitcast i8* %a8 to i32*
 
 ; CHECK: MemoryUse(2)
@@ -145,8 +145,8 @@ entry:
   call void @clobber8(i8* %p)
 
 ; CHECK: 3 = MemoryDef(2)
-; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
-  %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
+; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
+  %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
   br i1 undef, label %Loop.Body, label %Loop.End
 
 Loop.Body:
@@ -192,8 +192,8 @@ entry:
   call void @clobber8(i8* %p)
 
 ; CHECK: 3 = MemoryDef(2)
-; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
-  %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
+; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
+  %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
   br i1 undef, label %Loop.Body, label %Loop.End
 
 Loop.Body:
@@ -253,8 +253,8 @@ entry:
 ; CHECK-NEXT: call void @clobber
   call void @clobber8(i8* %p)
 ; CHECK: 3 = MemoryDef(2)
-; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
-  %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
+; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
+  %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
   br i1 undef, label %Loop.Pre, label %Loop.End
 
 Loop.Pre:
@@ -302,12 +302,12 @@ entry:
 ; CHECK-NEXT: store i8 42, i8* %ptr, !invariant.group !0
   store i8 42, i8* %ptr, !invariant.group !0
 ; CHECK: 2 = MemoryDef(1)
-; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
-  %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK-NEXT: call i8* @llvm.launder.invariant.group
+  %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; FIXME: This one could be CSEd.
 ; CHECK: 3 = MemoryDef(2)
-; CHECK: call i8* @llvm.invariant.group.barrier
-  %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group
+  %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: 4 = MemoryDef(3)
 ; CHECK-NEXT: call void @clobber8(i8* %ptr)
   call void @clobber8(i8* %ptr)
@@ -331,13 +331,13 @@ define i8 @unoptimizable2() {
 ; CHECK-NEXT: store i8 42, i8* %ptr, !invariant.group !0
   store i8 42, i8* %ptr, !invariant.group !0
 ; CHECK: 2 = MemoryDef(1)
-; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
-  %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK-NEXT: call i8* @llvm.launder.invariant.group
+  %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: 3 = MemoryDef(2)
   store i8 43, i8* %ptr
 ; CHECK: 4 = MemoryDef(3)
-; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
-  %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK-NEXT: call i8* @llvm.launder.invariant.group
+  %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: 5 = MemoryDef(4)
 ; CHECK-NEXT: call void @clobber8(i8* %ptr)
   call void @clobber8(i8* %ptr)
@@ -354,7 +354,7 @@ define i8 @unoptimizable2() {
 }
 
 
-declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 declare void @clobber(i32*)
 declare void @clobber8(i8*)
 declare void @use(i8* readonly)
diff --git a/llvm/test/Bitcode/upgrade-invariant-group-barrier.ll b/llvm/test/Bitcode/upgrade-invariant-group-barrier.ll
new file mode 100644 (file)
index 0000000..d187489
--- /dev/null
@@ -0,0 +1,22 @@
+; RUN: opt -S < %s | FileCheck %s
+
+; The intrinsic firstly only took i8*, then it was made polimorphic, then
+; it was renamed to launder.invariant.group
+define void @test(i8* %p1, i16* %p16) {
+; CHECK-LABEL: @test
+; CHECK: %p2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p1)
+; CHECK: %p3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p1)
+; CHECK: %p4 = call i16* @llvm.launder.invariant.group.p0i16(i16* %p16)
+  %p2 = call i8* @llvm.invariant.group.barrier(i8* %p1)
+  %p3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p1)
+  %p4 = call i16* @llvm.invariant.group.barrier.p0i16(i16* %p16)
+  ret void
+}
+
+; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable
+; CHECK: declare i8* @llvm.launder.invariant.group.p0i8(i8*)
+; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable
+; CHECK: declare i16* @llvm.launder.invariant.group.p0i16(i16*)
+declare i8* @llvm.invariant.group.barrier(i8*)
+declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+declare i16* @llvm.invariant.group.barrier.p0i16(i16*)
index 179dd51..34b2a56 100644 (file)
@@ -1,10 +1,10 @@
 ; RUN: llc -O0 -mtriple=arm64 < %s
 
-declare i8* @llvm.invariant.group.barrier(i8*)
+declare i8* @llvm.launder.invariant.group(i8*)
 
 define i8* @barrier(i8* %p) {
-; CHECK: bl llvm.invariant.group.barrier
-        %q = call i8* @llvm.invariant.group.barrier(i8* %p)
+; CHECK: bl llvm.launder.invariant.group
+        %q = call i8* @llvm.launder.invariant.group(i8* %p)
         ret i8* %q
 }
 
index 768d520..3a8b45f 100644 (file)
@@ -3,7 +3,7 @@ target datalayout = "A5"
 
 declare {}* @llvm.invariant.start.p5i8(i64, i8 addrspace(5)* nocapture) #0
 declare void @llvm.invariant.end.p5i8({}*, i64, i8 addrspace(5)* nocapture) #0
-declare i8 addrspace(5)* @llvm.invariant.group.barrier.p5i8(i8 addrspace(5)*) #1
+declare i8 addrspace(5)* @llvm.launder.invariant.group.p5i8(i8 addrspace(5)*) #1
 
 ; GCN-LABEL: {{^}}use_invariant_promotable_lds:
 ; GCN: buffer_load_dword
@@ -17,7 +17,7 @@ bb:
   store i32 %tmp3, i32 addrspace(5)* %tmp
   %tmp4 = call {}* @llvm.invariant.start.p5i8(i64 4, i8 addrspace(5)* %tmp1) #0
   call void @llvm.invariant.end.p5i8({}* %tmp4, i64 4, i8 addrspace(5)* %tmp1) #0
-  %tmp5 = call i8 addrspace(5)* @llvm.invariant.group.barrier.p5i8(i8 addrspace(5)* %tmp1) #1
+  %tmp5 = call i8 addrspace(5)* @llvm.launder.invariant.group.p5i8(i8 addrspace(5)* %tmp1) #1
   ret void
 }
 
index 6a51d2d..3964968 100644 (file)
@@ -39,10 +39,10 @@ define double @test_cos(float %F) {
         ret double %I
 }
 
-declare i8* @llvm.invariant.group.barrier(i8*)
+declare i8* @llvm.launder.invariant.group(i8*)
 
 define i8* @barrier(i8* %p) {
-        %q = call i8* @llvm.invariant.group.barrier(i8* %p)
+        %q = call i8* @llvm.launder.invariant.group(i8* %p)
         ret i8* %q
 }
 
diff --git a/llvm/test/Other/Inputs/invariant.group.barrier.ll b/llvm/test/Other/Inputs/invariant.group.barrier.ll
deleted file mode 100644 (file)
index 565b098..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt -S -gvn < %s | FileCheck %s
-; RUN: opt -S -newgvn < %s | FileCheck %s
-; RUN: opt -S -O3 < %s | FileCheck %s
-
-; This test check if optimizer is not proving equality based on mustalias
-; CHECK-LABEL: define void @dontProveEquality(i8* %a) 
-define void @dontProveEquality(i8* %a) {
-  %b = call i8* @llvm.invariant.group.barrier(i8* %a)
-  %r = i1 icmp eq i8* %b, i8* %a
-;CHECK: call void @use(%r)
-  call void @use(%r)
-}
-
-declare void @use(i1)
-declare i8* @llvm.invariant.group.barrier(i8 *)
similarity index 59%
rename from llvm/test/Other/invariant.group.barrier.ll
rename to llvm/test/Other/launder.invariant.group.ll
index 5ba4fcc..ebb2819 100644 (file)
@@ -4,7 +4,7 @@
 ; RUN: opt -S -O3 < %s | FileCheck %s
 
 ; These tests checks if passes with CSE functionality can do CSE on
-; invariant.group.barrier, that is prohibited if there is a memory clobber
+; launder.invariant.group, that is prohibited if there is a memory clobber
 ; between barriers call.
 
 ; CHECK-LABEL: define i8 @optimizable()
@@ -12,11 +12,11 @@ define i8 @optimizable() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group.p0i8
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; FIXME: This one could be CSE
-; CHECK: call i8* @llvm.invariant.group.barrier
-    %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group
+    %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
     call void @clobber(i8* %ptr)
 
@@ -35,11 +35,11 @@ define i8 @unoptimizable() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group.p0i8
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     call void @clobber(i8* %ptr)
-; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
-    %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group.p0i8
+    %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
     call void @clobber(i8* %ptr)
 ; CHECK: call void @use(i8* {{.*}}%ptr2)
@@ -56,11 +56,11 @@ entry:
 define i8 @unoptimizable2() {
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-; CHECK: call i8* @llvm.invariant.group.barrier
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     store i8 43, i8* %ptr
-; CHECK: call i8* @llvm.invariant.group.barrier
-    %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+; CHECK: call i8* @llvm.launder.invariant.group
+    %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
     call void @clobber(i8* %ptr)
 ; CHECK: call void @use(i8* {{.*}}%ptr2)
@@ -72,12 +72,23 @@ define i8 @unoptimizable2() {
     ret i8 %v
 }
 
+; This test check if optimizer is not proving equality based on mustalias
+; CHECK-LABEL: define void @dontProveEquality(i8* %a)
+define void @dontProveEquality(i8* %a) {
+  %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
+  %r = icmp eq i8* %b, %a
+;CHECK: call void @useBool(i1 %r)
+  call void @useBool(i1 %r)
+  ret void
+}
+
 declare void @use(i8* readonly)
+declare void @useBool(i1)
 
 declare void @clobber(i8*)
-; CHECK: Function Attrs: inaccessiblememonly nounwind{{$}}
-; CHECK-NEXT: declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
-declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable{{$}}
+; CHECK-NEXT: declare i8* @llvm.launder.invariant.group.p0i8(i8*)
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 
 !0 = !{}
 
index 042e58b..3ad1ca7 100644 (file)
@@ -6,10 +6,10 @@
 define void @foo() {
 enter:
   ; CHECK-NOT: !invariant.group
-  ; CHECK-NOT: @llvm.invariant.group.barrier.p0i8(
+  ; CHECK-NOT: @llvm.launder.invariant.group.p0i8(
   ; CHECK: %val = load i8, i8* @tmp, !tbaa
   %val = load i8, i8* @tmp, !invariant.group !0, !tbaa !{!1, !1, i64 0}
-  %ptr = call i8* @llvm.invariant.group.barrier.p0i8(i8* @tmp)
+  %ptr = call i8* @llvm.launder.invariant.group.p0i8(i8* @tmp)
   
   ; CHECK: store i8 42, i8* @tmp
   store i8 42, i8* %ptr, !invariant.group !0
@@ -18,7 +18,7 @@ enter:
 }
 ; CHECK-LABEL: }
 
-declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 
 !0 = !{!"something"}
 !1 = !{!"x", !0}
index 1bc1f49..8135087 100644 (file)
@@ -25,7 +25,7 @@ define i8 @optimizable1() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     %a = load i8, i8* %ptr, !invariant.group !0
     
     call void @foo(i8* %ptr2); call to use %ptr2
@@ -242,7 +242,7 @@ define i8 @optimizable4() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK-NOT: load
     %a = load i8, i8* %ptr2, !invariant.group !0
     
@@ -314,7 +314,7 @@ entry:
 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
     store i8 %unknownValue, i8* %ptr, !invariant.group !0 
 
-    %newPtr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+    %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK-NOT: load
     %d = load i8, i8* %newPtr2, !invariant.group !0
 ; CHECK: ret i8 %unknownValue
@@ -441,7 +441,7 @@ declare void @_ZN1A3fooEv(%struct.A*)
 declare void @_ZN1AC1Ev(%struct.A*)
 declare void @fooBit(i1*, i1)
 
-declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 
 ; Function Attrs: nounwind
 declare void @llvm.assume(i1 %cmp.vtables) #0
index 80cd411..744ab91 100644 (file)
@@ -33,7 +33,7 @@ enter:
   store i32 %val, i32* %valptr
   
   %0 = bitcast i32* %valptr to i8*
-  %barr = call i8* @llvm.invariant.group.barrier(i8* %0)
+  %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
   
   %val2 = load i32, i32* %1
@@ -41,7 +41,7 @@ enter:
   ret void
 }
 
-; We can't step through invariant.group.barrier here, because that would change
+; We can't step through launder.invariant.group here, because that would change
 ; this load in @usage_of_globals()
 ; val = load i32, i32* %ptrVal, !invariant.group !0 
 ; into 
@@ -54,7 +54,7 @@ enter:
   store i32 13, i32* @tmp3, !invariant.group !0
   
   %0 = bitcast i32* @tmp3 to i8*
-  %barr = call i8* @llvm.invariant.group.barrier(i8* %0)
+  %barr = call i8* @llvm.launder.invariant.group(i8* %0)
   %1 = bitcast i8* %barr to i32*
   
   store i32* %1, i32** @ptrToTmp3
@@ -74,6 +74,6 @@ entry:
 
 declare void @changeTmp3ValAndCallBarrierInside()
 
-declare i8* @llvm.invariant.group.barrier(i8*)
+declare i8* @llvm.launder.invariant.group(i8*)
 
 !0 = !{!"something"}
index 9839fc4..d5890f1 100644 (file)
@@ -26,7 +26,7 @@ define i8 @optimizable1() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     %a = load i8, i8* %ptr, !invariant.group !0
     
     call void @foo(i8* %ptr2); call to use %ptr2
@@ -243,8 +243,7 @@ define i8 @optimizable4() {
 entry:
     %ptr = alloca i8
     store i8 42, i8* %ptr, !invariant.group !0
-    %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
-; CHECK-NOT: load
+    %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     %a = load i8, i8* %ptr2, !invariant.group !0
     
 ; CHECK: ret i8 42
@@ -315,7 +314,7 @@ entry:
 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
     store i8 %unknownValue, i8* %ptr, !invariant.group !0 
 
-    %newPtr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
+    %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
 ; CHECK-NOT: load
     %d = load i8, i8* %newPtr2, !invariant.group !0
 ; CHECK: ret i8 %unknownValue
@@ -442,7 +441,7 @@ declare void @_ZN1A3fooEv(%struct.A*)
 declare void @_ZN1AC1Ev(%struct.A*)
 declare void @fooBit(i1*, i1)
 
-declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)
 
 ; Function Attrs: nounwind
 declare void @llvm.assume(i1 %cmp.vtables) #0