llvm.org GIT mirror llvm / 9648b46
Rename invariant.group.barrier to launder.invariant.group 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331448 91177308-0d34-0410-b5e6-96231b3b80d8 Piotr Padlewski 1 year, 6 months ago
25 changed file(s) with 227 addition(s) and 200 deletion(s). Raw diff Collapse all Expand all
53175317 The existence of the ``invariant.group`` metadata on the instruction tells
53185318 the optimizer that every ``load`` and ``store`` to the same pointer operand
53195319 within the same invariant group can be assumed to load or store the same
5320 value (but see the ``llvm.invariant.group.barrier`` intrinsic which affects
5320 value (but see the ``llvm.launder.invariant.group`` intrinsic which affects
53215321 when two pointers are considered the same). Pointers returned by bitcast or
53225322 getelementptr with only zero indices are considered the same.
53235323
53425342 store i8 %unknownValue, i8* %ptr, !invariant.group !0 ; Can assume that %unknownValue == 42
53435343
53445344 call void @foo(i8* %ptr)
5345 %newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
5346 %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through invariant.group.barrier to get value of %ptr
5345 %newPtr2 = call i8* @llvm.launder.invariant.group(i8* %ptr)
5346 %d = load i8, i8* %newPtr2, !invariant.group !0 ; Can't step through launder.invariant.group to get value of %ptr
53475347
53485348 ...
53495349 declare void @foo(i8*)
53505350 declare i8* @getPointer(i8*)
5351 declare i8* @llvm.invariant.group.barrier(i8*)
5351 declare i8* @llvm.launder.invariant.group(i8*)
53525352
53535353 !0 = !{!"magic ptr"}
53545354 !1 = !{!"other ptr"}
1290712907
1290812908 This intrinsic indicates that the memory is mutable again.
1290912909
12910 '``llvm.invariant.group.barrier``' Intrinsic
12910 '``llvm.launder.invariant.group``' Intrinsic
1291112911 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1291212912
1291312913 Syntax:
1291812918
1291912919 ::
1292012920
12921 declare i8* @llvm.invariant.group.barrier.p0i8(i8* )
12922
12923 Overview:
12924 """""""""
12925
12926 The '``llvm.invariant.group.barrier``' intrinsic can be used when an invariant
12921 declare i8* @llvm.launder.invariant.group.p0i8(i8* )
12922
12923 Overview:
12924 """""""""
12925
12926 The '``llvm.launder.invariant.group``' intrinsic can be used when an invariant
1292712927 established by invariant.group metadata no longer holds, to obtain a new pointer
1292812928 value that does not carry the invariant information. It is an experimental
1292912929 intrinsic, which means that its semantics might change in the future.
1293212932 Arguments:
1293312933 """"""""""
1293412934
12935 The ``llvm.invariant.group.barrier`` takes only one argument, which is
12935 The ``llvm.launder.invariant.group`` takes only one argument, which is
1293612936 the pointer to the memory for which the ``invariant.group`` no longer holds.
1293712937
1293812938 Semantics:
1294012940
1294112941 Returns another pointer that aliases its argument but which is considered different
1294212942 for the purposes of ``load``/``store`` ``invariant.group`` metadata.
12943 It does not read any accessible memory and the execution can be speculated.
1294312944
1294412945 .. _constrainedfp:
1294512946
106106 have changed. Alignment is no longer an argument, and are instead conveyed as
107107 parameter attributes.
108108
109 * invariant.group.barrier has been renamed to launder.invariant.group.
110
109111 Changes to the ARM Backend
110112 --------------------------
111113
19611961 Name);
19621962 }
19631963
1964 /// Create an invariant.group.barrier intrinsic call, that stops
1965 /// optimizer to propagate equality using invariant.group metadata.
1966 /// If Ptr type is different from pointer to i8, it's casted to pointer to i8
1967 /// in the same address space before call and casted back to Ptr type after
1968 /// call.
1969 Value *CreateInvariantGroupBarrier(Value *Ptr) {
1964 /// Create a launder.invariant.group intrinsic call. If Ptr type is
1965 /// different from pointer to i8, it's casted to pointer to i8 in the same
1966 /// address space before call and casted back to Ptr type after call.
1967 Value *CreateLaunderInvariantGroup(Value *Ptr) {
19701968 assert(isa(Ptr->getType()) &&
1971 "invariant.group.barrier only applies to pointers.");
1969 "launder.invariant.group only applies to pointers.");
19721970 auto *PtrType = Ptr->getType();
19731971 auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
19741972 if (PtrType != Int8PtrTy)
19751973 Ptr = CreateBitCast(Ptr, Int8PtrTy);
19761974 Module *M = BB->getParent()->getParent();
1977 Function *FnInvariantGroupBarrier = Intrinsic::getDeclaration(
1978 M, Intrinsic::invariant_group_barrier, {Int8PtrTy});
1979
1980 assert(FnInvariantGroupBarrier->getReturnType() == Int8PtrTy &&
1981 FnInvariantGroupBarrier->getFunctionType()->getParamType(0) ==
1975 Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration(
1976 M, Intrinsic::launder_invariant_group, {Int8PtrTy});
1977
1978 assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&
1979 FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==
19821980 Int8PtrTy &&
1983 "InvariantGroupBarrier should take and return the same type");
1984
1985 CallInst *Fn = CreateCall(FnInvariantGroupBarrier, {Ptr});
1981 "LaunderInvariantGroup should take and return the same type");
1982
1983 CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr});
19861984
19871985 if (PtrType != Int8PtrTy)
19881986 return CreateBitCast(Fn, PtrType);
709709 llvm_anyptr_ty],
710710 [IntrArgMemOnly, NoCapture<2>]>;
711711
712 // invariant.group.barrier can't be marked with 'readnone' (IntrNoMem),
712 // launder.invariant.group can't be marked with 'readnone' (IntrNoMem),
713713 // because it would cause CSE of two barriers with the same argument.
714714 // Inaccessiblememonly says that the barrier doesn't read the argument,
715715 // but it changes state not accessible to this module. This way
721721 // it would remove barrier.
722722 // Note that it is still experimental, which means that its semantics
723723 // might change in the future.
724 def int_invariant_group_barrier : Intrinsic<[llvm_anyptr_ty],
724 def int_launder_invariant_group : Intrinsic<[llvm_anyptr_ty],
725725 [LLVMMatchType<0>],
726 [IntrInaccessibleMemOnly]>;
726 [IntrInaccessibleMemOnly, IntrSpeculatable]>;
727727
728728 //===------------------------ Stackmap Intrinsics -------------------------===//
729729 //
508508 static_cast(this)->stripPointerCasts());
509509 }
510510
511 /// Strip off pointer casts, all-zero GEPs, aliases and barriers.
511 /// Strip off pointer casts, all-zero GEPs, aliases and invariant group
512 /// info.
512513 ///
513514 /// Returns the original uncasted value. If this is called on a non-pointer
514515 /// value, it returns 'this'. This function should be used only in
515516 /// Alias analysis.
516 const Value *stripPointerCastsAndBarriers() const;
517 Value *stripPointerCastsAndBarriers() {
517 const Value *stripPointerCastsAndInvariantGroups() const;
518 Value *stripPointerCastsAndInvariantGroups() {
518519 return const_cast(
519 static_cast(this)->stripPointerCastsAndBarriers());
520 static_cast(this)->stripPointerCastsAndInvariantGroups());
520521 }
521522
522523 /// Strip off pointer casts and all-zero GEPs.
984984 const GEPOperator *GEP2,
985985 uint64_t V2Size,
986986 const DataLayout &DL) {
987 assert(GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
988 GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
987 assert(GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() ==
988 GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() &&
989989 GEP1->getPointerOperandType() == GEP2->getPointerOperandType() &&
990990 "Expected GEPs with the same pointer operand");
991991
12631263 // If we know the two GEPs are based off of the exact same pointer (and not
12641264 // just the same underlying object), see if that tells us anything about
12651265 // the resulting pointers.
1266 if (GEP1->getPointerOperand()->stripPointerCastsAndBarriers() ==
1267 GEP2->getPointerOperand()->stripPointerCastsAndBarriers() &&
1266 if (GEP1->getPointerOperand()->stripPointerCastsAndInvariantGroups() ==
1267 GEP2->getPointerOperand()->stripPointerCastsAndInvariantGroups() &&
12681268 GEP1->getPointerOperandType() == GEP2->getPointerOperandType()) {
12691269 AliasResult R = aliasSameBasePointerGEPs(GEP1, V1Size, GEP2, V2Size, DL);
12701270 // If we couldn't find anything interesting, don't abandon just yet.
15771577 return NoAlias;
15781578
15791579 // Strip off any casts if they exist.
1580 V1 = V1->stripPointerCastsAndBarriers();
1581 V2 = V2->stripPointerCastsAndBarriers();
1580 V1 = V1->stripPointerCastsAndInvariantGroups();
1581 V2 = V2->stripPointerCastsAndInvariantGroups();
15821582
15831583 // If V1 or V2 is undef, the result is NoAlias because we can always pick a
15841584 // value for undef that aliases nothing in the program.
351351 const Instruction *I) {
352352 // If the memory can't be changed, then loads of the memory can't be
353353 // clobbered.
354 //
355 // FIXME: We should handle invariant groups, as well. It's a bit harder,
356 // because we need to pay close attention to invariant group barriers.
357354 return isa(I) && (I->getMetadata(LLVMContext::MD_invariant_load) ||
358355 AA.pointsToConstantMemory(cast(I)->
359356 getPointerOperand()));
16671667 InsertedInsts.insert(ExtVal);
16681668 return true;
16691669 }
1670 case Intrinsic::invariant_group_barrier:
1670 case Intrinsic::launder_invariant_group:
16711671 II->replaceAllUsesWith(II->getArgOperand(0));
16721672 II->eraseFromParent();
16731673 return true;
14431443 updateValueMap(II, ResultReg);
14441444 return true;
14451445 }
1446 case Intrinsic::invariant_group_barrier:
1446 case Intrinsic::launder_invariant_group:
14471447 case Intrinsic::expect: {
14481448 unsigned ResultReg = getRegForValue(II->getArgOperand(0));
14491449 if (!ResultReg)
57095709 }
57105710 case Intrinsic::annotation:
57115711 case Intrinsic::ptr_annotation:
5712 case Intrinsic::invariant_group_barrier:
5712 case Intrinsic::launder_invariant_group:
57135713 // Drop the intrinsic, but forward the value
57145714 setValue(&I, getValue(I.getOperand(0)));
57155715 return nullptr;
527527 return true;
528528 }
529529 }
530 if (Name.startswith("invariant.group.barrier")) {
531 // Rename invariant.group.barrier to launder.invariant.group
532 auto Args = F->getFunctionType()->params();
533 Type* ObjectPtr[1] = {Args[0]};
534 rename(F);
535 NewFn = Intrinsic::getDeclaration(F->getParent(),
536 Intrinsic::launder_invariant_group, ObjectPtr);
537 return true;
538
539 }
540
530541 break;
531542 }
532543 case 'm': {
498498 enum PointerStripKind {
499499 PSK_ZeroIndices,
500500 PSK_ZeroIndicesAndAliases,
501 PSK_ZeroIndicesAndAliasesAndBarriers,
501 PSK_ZeroIndicesAndAliasesAndInvariantGroups,
502502 PSK_InBoundsConstantIndices,
503503 PSK_InBounds
504504 };
517517 if (auto *GEP = dyn_cast(V)) {
518518 switch (StripKind) {
519519 case PSK_ZeroIndicesAndAliases:
520 case PSK_ZeroIndicesAndAliasesAndBarriers:
520 case PSK_ZeroIndicesAndAliasesAndInvariantGroups:
521521 case PSK_ZeroIndices:
522522 if (!GEP->hasAllZeroIndices())
523523 return V;
545545 V = RV;
546546 continue;
547547 }
548 // The result of invariant.group.barrier must alias it's argument,
548 // The result of launder.invariant.group must alias it's argument,
549549 // but it can't be marked with returned attribute, that's why it needs
550550 // special case.
551 if (StripKind == PSK_ZeroIndicesAndAliasesAndBarriers &&
552 CS.getIntrinsicID() == Intrinsic::invariant_group_barrier) {
551 if (StripKind == PSK_ZeroIndicesAndAliasesAndInvariantGroups &&
552 CS.getIntrinsicID() == Intrinsic::launder_invariant_group) {
553553 V = CS.getArgOperand(0);
554554 continue;
555555 }
575575 return stripPointerCastsAndOffsets(this);
576576 }
577577
578 const Value *Value::stripPointerCastsAndBarriers() const {
579 return stripPointerCastsAndOffsets(
578 const Value *Value::stripPointerCastsAndInvariantGroups() const {
579 return stripPointerCastsAndOffsets(
580580 this);
581581 }
582582
453453 case Intrinsic::lifetime_end:
454454 case Intrinsic::invariant_start:
455455 case Intrinsic::invariant_end:
456 case Intrinsic::invariant_group_barrier:
456 case Intrinsic::launder_invariant_group:
457457 case Intrinsic::objectsize:
458458 return true;
459459 default:
877877 }
878878 case Intrinsic::invariant_start:
879879 case Intrinsic::invariant_end:
880 case Intrinsic::invariant_group_barrier:
880 case Intrinsic::launder_invariant_group:
881881 Intr->eraseFromParent();
882882 // FIXME: I think the invariant marker should still theoretically apply,
883883 // but the intrinsics need to be changed to accept pointers with any
0 ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
11 ;
22 ; Currently, MemorySSA doesn't support invariant groups. So, we should ignore
3 ; invariant.group.barrier intrinsics entirely. We'll need to pay attention to
3 ; launder.invariant.group intrinsics entirely. We'll need to pay attention to
44 ; them when/if we decide to support invariant groups.
55
66 @g = external global i32
1616
1717 %1 = bitcast i32* %a to i8*
1818 ; CHECK: 3 = MemoryDef(2)
19 ; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
20 %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
19 ; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
20 %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
2121 %a32 = bitcast i8* %a8 to i32*
2222
2323 ; This have to be MemoryUse(2), because we can't skip the barrier based on
3535
3636 %1 = bitcast i32* %a to i8*
3737 ; CHECK: 2 = MemoryDef(1)
38 ; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
39 %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
38 ; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
39 %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
4040 %a32 = bitcast i8* %a8 to i32*
4141
4242 ; We can skip the barrier only if the "skip" is not based on !invariant.group.
5454
5555 %1 = bitcast i32* %a to i8*
5656 ; CHECK: 1 = MemoryDef(liveOnEntry)
57 ; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
58 %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
57 ; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
58 %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
5959 %a32 = bitcast i8* %a8 to i32*
6060
6161 ; We can skip the barrier only if the "skip" is not based on !invariant.group.
8585 store i32 1, i32* @g, align 4
8686 %1 = bitcast i32* %a to i8*
8787 ; CHECK: 3 = MemoryDef(2)
88 ; CHECK-NEXT: %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
89 %a8 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %1)
88 ; CHECK-NEXT: %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
89 %a8 = call i8* @llvm.launder.invariant.group.p0i8(i8* %1)
9090 %a32 = bitcast i8* %a8 to i32*
9191
9292 ; CHECK: MemoryUse(2)
144144 call void @clobber8(i8* %p)
145145
146146 ; CHECK: 3 = MemoryDef(2)
147 ; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
148 %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
147 ; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
148 %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
149149 br i1 undef, label %Loop.Body, label %Loop.End
150150
151151 Loop.Body:
191191 call void @clobber8(i8* %p)
192192
193193 ; CHECK: 3 = MemoryDef(2)
194 ; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
195 %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
194 ; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
195 %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
196196 br i1 undef, label %Loop.Body, label %Loop.End
197197
198198 Loop.Body:
252252 ; CHECK-NEXT: call void @clobber
253253 call void @clobber8(i8* %p)
254254 ; CHECK: 3 = MemoryDef(2)
255 ; CHECK-NEXT: %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
256 %after = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p)
255 ; CHECK-NEXT: %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
256 %after = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
257257 br i1 undef, label %Loop.Pre, label %Loop.End
258258
259259 Loop.Pre:
301301 ; CHECK-NEXT: store i8 42, i8* %ptr, !invariant.group !0
302302 store i8 42, i8* %ptr, !invariant.group !0
303303 ; CHECK: 2 = MemoryDef(1)
304 ; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
305 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
304 ; CHECK-NEXT: call i8* @llvm.launder.invariant.group
305 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
306306 ; FIXME: This one could be CSEd.
307307 ; CHECK: 3 = MemoryDef(2)
308 ; CHECK: call i8* @llvm.invariant.group.barrier
309 %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
308 ; CHECK: call i8* @llvm.launder.invariant.group
309 %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
310310 ; CHECK: 4 = MemoryDef(3)
311311 ; CHECK-NEXT: call void @clobber8(i8* %ptr)
312312 call void @clobber8(i8* %ptr)
330330 ; CHECK-NEXT: store i8 42, i8* %ptr, !invariant.group !0
331331 store i8 42, i8* %ptr, !invariant.group !0
332332 ; CHECK: 2 = MemoryDef(1)
333 ; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
334 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
333 ; CHECK-NEXT: call i8* @llvm.launder.invariant.group
334 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
335335 ; CHECK: 3 = MemoryDef(2)
336336 store i8 43, i8* %ptr
337337 ; CHECK: 4 = MemoryDef(3)
338 ; CHECK-NEXT: call i8* @llvm.invariant.group.barrier
339 %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
338 ; CHECK-NEXT: call i8* @llvm.launder.invariant.group
339 %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
340340 ; CHECK: 5 = MemoryDef(4)
341341 ; CHECK-NEXT: call void @clobber8(i8* %ptr)
342342 call void @clobber8(i8* %ptr)
353353 }
354354
355355
356 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
356 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
357357 declare void @clobber(i32*)
358358 declare void @clobber8(i8*)
359359 declare void @use(i8* readonly)
0 ; RUN: opt -S < %s | FileCheck %s
1
2 ; The intrinsic firstly only took i8*, then it was made polimorphic, then
3 ; it was renamed to launder.invariant.group
4 define void @test(i8* %p1, i16* %p16) {
5 ; CHECK-LABEL: @test
6 ; CHECK: %p2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p1)
7 ; CHECK: %p3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p1)
8 ; CHECK: %p4 = call i16* @llvm.launder.invariant.group.p0i16(i16* %p16)
9 %p2 = call i8* @llvm.invariant.group.barrier(i8* %p1)
10 %p3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %p1)
11 %p4 = call i16* @llvm.invariant.group.barrier.p0i16(i16* %p16)
12 ret void
13 }
14
15 ; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable
16 ; CHECK: declare i8* @llvm.launder.invariant.group.p0i8(i8*)
17 ; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable
18 ; CHECK: declare i16* @llvm.launder.invariant.group.p0i16(i16*)
19 declare i8* @llvm.invariant.group.barrier(i8*)
20 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
21 declare i16* @llvm.invariant.group.barrier.p0i16(i16*)
0 ; RUN: llc -O0 -mtriple=arm64 < %s
11
2 declare i8* @llvm.invariant.group.barrier(i8*)
2 declare i8* @llvm.launder.invariant.group(i8*)
33
44 define i8* @barrier(i8* %p) {
5 ; CHECK: bl llvm.invariant.group.barrier
6 %q = call i8* @llvm.invariant.group.barrier(i8* %p)
5 ; CHECK: bl llvm.launder.invariant.group
6 %q = call i8* @llvm.launder.invariant.group(i8* %p)
77 ret i8* %q
88 }
99
22
33 declare {}* @llvm.invariant.start.p5i8(i64, i8 addrspace(5)* nocapture) #0
44 declare void @llvm.invariant.end.p5i8({}*, i64, i8 addrspace(5)* nocapture) #0
5 declare i8 addrspace(5)* @llvm.invariant.group.barrier.p5i8(i8 addrspace(5)*) #1
5 declare i8 addrspace(5)* @llvm.launder.invariant.group.p5i8(i8 addrspace(5)*) #1
66
77 ; GCN-LABEL: {{^}}use_invariant_promotable_lds:
88 ; GCN: buffer_load_dword
1616 store i32 %tmp3, i32 addrspace(5)* %tmp
1717 %tmp4 = call {}* @llvm.invariant.start.p5i8(i64 4, i8 addrspace(5)* %tmp1) #0
1818 call void @llvm.invariant.end.p5i8({}* %tmp4, i64 4, i8 addrspace(5)* %tmp1) #0
19 %tmp5 = call i8 addrspace(5)* @llvm.invariant.group.barrier.p5i8(i8 addrspace(5)* %tmp1) #1
19 %tmp5 = call i8 addrspace(5)* @llvm.launder.invariant.group.p5i8(i8 addrspace(5)* %tmp1) #1
2020 ret void
2121 }
2222
3838 ret double %I
3939 }
4040
41 declare i8* @llvm.invariant.group.barrier(i8*)
41 declare i8* @llvm.launder.invariant.group(i8*)
4242
4343 define i8* @barrier(i8* %p) {
44 %q = call i8* @llvm.invariant.group.barrier(i8* %p)
44 %q = call i8* @llvm.launder.invariant.group(i8* %p)
4545 ret i8* %q
4646 }
4747
+0
-15
test/Other/Inputs/invariant.group.barrier.ll less more
None ; RUN: opt -S -gvn < %s | FileCheck %s
1 ; RUN: opt -S -newgvn < %s | FileCheck %s
2 ; RUN: opt -S -O3 < %s | FileCheck %s
3
4 ; This test check if optimizer is not proving equality based on mustalias
5 ; CHECK-LABEL: define void @dontProveEquality(i8* %a)
6 define void @dontProveEquality(i8* %a) {
7 %b = call i8* @llvm.invariant.group.barrier(i8* %a)
8 %r = i1 icmp eq i8* %b, i8* %a
9 ;CHECK: call void @use(%r)
10 call void @use(%r)
11 }
12
13 declare void @use(i1)
14 declare i8* @llvm.invariant.group.barrier(i8 *)
+0
-83
test/Other/invariant.group.barrier.ll less more
None ; RUN: opt -S -early-cse < %s | FileCheck %s
1 ; RUN: opt -S -gvn < %s | FileCheck %s
2 ; RUN: opt -S -newgvn < %s | FileCheck %s
3 ; RUN: opt -S -O3 < %s | FileCheck %s
4
5 ; These tests checks if passes with CSE functionality can do CSE on
6 ; invariant.group.barrier, that is prohibited if there is a memory clobber
7 ; between barriers call.
8
9 ; CHECK-LABEL: define i8 @optimizable()
10 define i8 @optimizable() {
11 entry:
12 %ptr = alloca i8
13 store i8 42, i8* %ptr, !invariant.group !0
14 ; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
15 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
16 ; FIXME: This one could be CSE
17 ; CHECK: call i8* @llvm.invariant.group.barrier
18 %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
19 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
20 call void @clobber(i8* %ptr)
21
22 ; CHECK: call void @use(i8* {{.*}}%ptr2)
23 call void @use(i8* %ptr2)
24 ; CHECK: call void @use(i8* {{.*}}%ptr3)
25 call void @use(i8* %ptr3)
26 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
27 %v = load i8, i8* %ptr3, !invariant.group !0
28
29 ret i8 %v
30 }
31
32 ; CHECK-LABEL: define i8 @unoptimizable()
33 define i8 @unoptimizable() {
34 entry:
35 %ptr = alloca i8
36 store i8 42, i8* %ptr, !invariant.group !0
37 ; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
38 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
39 call void @clobber(i8* %ptr)
40 ; CHECK: call i8* @llvm.invariant.group.barrier.p0i8
41 %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
42 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
43 call void @clobber(i8* %ptr)
44 ; CHECK: call void @use(i8* {{.*}}%ptr2)
45 call void @use(i8* %ptr2)
46 ; CHECK: call void @use(i8* {{.*}}%ptr3)
47 call void @use(i8* %ptr3)
48 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
49 %v = load i8, i8* %ptr3, !invariant.group !0
50
51 ret i8 %v
52 }
53
54 ; CHECK-LABEL: define i8 @unoptimizable2()
55 define i8 @unoptimizable2() {
56 %ptr = alloca i8
57 store i8 42, i8* %ptr, !invariant.group !0
58 ; CHECK: call i8* @llvm.invariant.group.barrier
59 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
60 store i8 43, i8* %ptr
61 ; CHECK: call i8* @llvm.invariant.group.barrier
62 %ptr3 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
63 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
64 call void @clobber(i8* %ptr)
65 ; CHECK: call void @use(i8* {{.*}}%ptr2)
66 call void @use(i8* %ptr2)
67 ; CHECK: call void @use(i8* {{.*}}%ptr3)
68 call void @use(i8* %ptr3)
69 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
70 %v = load i8, i8* %ptr3, !invariant.group !0
71 ret i8 %v
72 }
73
74 declare void @use(i8* readonly)
75
76 declare void @clobber(i8*)
77 ; CHECK: Function Attrs: inaccessiblememonly nounwind{{$}}
78 ; CHECK-NEXT: declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
79 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
80
81 !0 = !{}
82
0 ; RUN: opt -S -early-cse < %s | FileCheck %s
1 ; RUN: opt -S -gvn < %s | FileCheck %s
2 ; RUN: opt -S -newgvn < %s | FileCheck %s
3 ; RUN: opt -S -O3 < %s | FileCheck %s
4
5 ; These tests checks if passes with CSE functionality can do CSE on
6 ; launder.invariant.group, that is prohibited if there is a memory clobber
7 ; between barriers call.
8
9 ; CHECK-LABEL: define i8 @optimizable()
10 define i8 @optimizable() {
11 entry:
12 %ptr = alloca i8
13 store i8 42, i8* %ptr, !invariant.group !0
14 ; CHECK: call i8* @llvm.launder.invariant.group.p0i8
15 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
16 ; FIXME: This one could be CSE
17 ; CHECK: call i8* @llvm.launder.invariant.group
18 %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
19 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
20 call void @clobber(i8* %ptr)
21
22 ; CHECK: call void @use(i8* {{.*}}%ptr2)
23 call void @use(i8* %ptr2)
24 ; CHECK: call void @use(i8* {{.*}}%ptr3)
25 call void @use(i8* %ptr3)
26 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
27 %v = load i8, i8* %ptr3, !invariant.group !0
28
29 ret i8 %v
30 }
31
32 ; CHECK-LABEL: define i8 @unoptimizable()
33 define i8 @unoptimizable() {
34 entry:
35 %ptr = alloca i8
36 store i8 42, i8* %ptr, !invariant.group !0
37 ; CHECK: call i8* @llvm.launder.invariant.group.p0i8
38 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
39 call void @clobber(i8* %ptr)
40 ; CHECK: call i8* @llvm.launder.invariant.group.p0i8
41 %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
42 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
43 call void @clobber(i8* %ptr)
44 ; CHECK: call void @use(i8* {{.*}}%ptr2)
45 call void @use(i8* %ptr2)
46 ; CHECK: call void @use(i8* {{.*}}%ptr3)
47 call void @use(i8* %ptr3)
48 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
49 %v = load i8, i8* %ptr3, !invariant.group !0
50
51 ret i8 %v
52 }
53
54 ; CHECK-LABEL: define i8 @unoptimizable2()
55 define i8 @unoptimizable2() {
56 %ptr = alloca i8
57 store i8 42, i8* %ptr, !invariant.group !0
58 ; CHECK: call i8* @llvm.launder.invariant.group
59 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
60 store i8 43, i8* %ptr
61 ; CHECK: call i8* @llvm.launder.invariant.group
62 %ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
63 ; CHECK: call void @clobber(i8* {{.*}}%ptr)
64 call void @clobber(i8* %ptr)
65 ; CHECK: call void @use(i8* {{.*}}%ptr2)
66 call void @use(i8* %ptr2)
67 ; CHECK: call void @use(i8* {{.*}}%ptr3)
68 call void @use(i8* %ptr3)
69 ; CHECK: load i8, i8* %ptr3, {{.*}}!invariant.group
70 %v = load i8, i8* %ptr3, !invariant.group !0
71 ret i8 %v
72 }
73
74 ; This test check if optimizer is not proving equality based on mustalias
75 ; CHECK-LABEL: define void @dontProveEquality(i8* %a)
76 define void @dontProveEquality(i8* %a) {
77 %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
78 %r = icmp eq i8* %b, %a
79 ;CHECK: call void @useBool(i1 %r)
80 call void @useBool(i1 %r)
81 ret void
82 }
83
84 declare void @use(i8* readonly)
85 declare void @useBool(i1)
86
87 declare void @clobber(i8*)
88 ; CHECK: Function Attrs: inaccessiblememonly nounwind speculatable{{$}}
89 ; CHECK-NEXT: declare i8* @llvm.launder.invariant.group.p0i8(i8*)
90 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
91
92 !0 = !{}
93
55 define void @foo() {
66 enter:
77 ; CHECK-NOT: !invariant.group
8 ; CHECK-NOT: @llvm.invariant.group.barrier.p0i8(
8 ; CHECK-NOT: @llvm.launder.invariant.group.p0i8(
99 ; CHECK: %val = load i8, i8* @tmp, !tbaa
1010 %val = load i8, i8* @tmp, !invariant.group !0, !tbaa !{!1, !1, i64 0}
11 %ptr = call i8* @llvm.invariant.group.barrier.p0i8(i8* @tmp)
11 %ptr = call i8* @llvm.launder.invariant.group.p0i8(i8* @tmp)
1212
1313 ; CHECK: store i8 42, i8* @tmp
1414 store i8 42, i8* %ptr, !invariant.group !0
1717 }
1818 ; CHECK-LABEL: }
1919
20 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
20 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
2121
2222 !0 = !{!"something"}
2323 !1 = !{!"x", !0}
2424 entry:
2525 %ptr = alloca i8
2626 store i8 42, i8* %ptr, !invariant.group !0
27 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
27 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
2828 %a = load i8, i8* %ptr, !invariant.group !0
2929
3030 call void @foo(i8* %ptr2); call to use %ptr2
241241 entry:
242242 %ptr = alloca i8
243243 store i8 42, i8* %ptr, !invariant.group !0
244 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
244 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
245245 ; CHECK-NOT: load
246246 %a = load i8, i8* %ptr2, !invariant.group !0
247247
313313 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
314314 store i8 %unknownValue, i8* %ptr, !invariant.group !0
315315
316 %newPtr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
316 %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
317317 ; CHECK-NOT: load
318318 %d = load i8, i8* %newPtr2, !invariant.group !0
319319 ; CHECK: ret i8 %unknownValue
440440 declare void @_ZN1AC1Ev(%struct.A*)
441441 declare void @fooBit(i1*, i1)
442442
443 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
443 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
444444
445445 ; Function Attrs: nounwind
446446 declare void @llvm.assume(i1 %cmp.vtables) #0
3232 store i32 %val, i32* %valptr
3333
3434 %0 = bitcast i32* %valptr to i8*
35 %barr = call i8* @llvm.invariant.group.barrier(i8* %0)
35 %barr = call i8* @llvm.launder.invariant.group(i8* %0)
3636 %1 = bitcast i8* %barr to i32*
3737
3838 %val2 = load i32, i32* %1
4040 ret void
4141 }
4242
43 ; We can't step through invariant.group.barrier here, because that would change
43 ; We can't step through launder.invariant.group here, because that would change
4444 ; this load in @usage_of_globals()
4545 ; val = load i32, i32* %ptrVal, !invariant.group !0
4646 ; into
5353 store i32 13, i32* @tmp3, !invariant.group !0
5454
5555 %0 = bitcast i32* @tmp3 to i8*
56 %barr = call i8* @llvm.invariant.group.barrier(i8* %0)
56 %barr = call i8* @llvm.launder.invariant.group(i8* %0)
5757 %1 = bitcast i8* %barr to i32*
5858
5959 store i32* %1, i32** @ptrToTmp3
7373
7474 declare void @changeTmp3ValAndCallBarrierInside()
7575
76 declare i8* @llvm.invariant.group.barrier(i8*)
76 declare i8* @llvm.launder.invariant.group(i8*)
7777
7878 !0 = !{!"something"}
2525 entry:
2626 %ptr = alloca i8
2727 store i8 42, i8* %ptr, !invariant.group !0
28 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
28 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
2929 %a = load i8, i8* %ptr, !invariant.group !0
3030
3131 call void @foo(i8* %ptr2); call to use %ptr2
242242 entry:
243243 %ptr = alloca i8
244244 store i8 42, i8* %ptr, !invariant.group !0
245 %ptr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
246 ; CHECK-NOT: load
245 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
247246 %a = load i8, i8* %ptr2, !invariant.group !0
248247
249248 ; CHECK: ret i8 42
314313 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
315314 store i8 %unknownValue, i8* %ptr, !invariant.group !0
316315
317 %newPtr2 = call i8* @llvm.invariant.group.barrier.p0i8(i8* %ptr)
316 %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
318317 ; CHECK-NOT: load
319318 %d = load i8, i8* %newPtr2, !invariant.group !0
320319 ; CHECK: ret i8 %unknownValue
441440 declare void @_ZN1AC1Ev(%struct.A*)
442441 declare void @fooBit(i1*, i1)
443442
444 declare i8* @llvm.invariant.group.barrier.p0i8(i8*)
443 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
445444
446445 ; Function Attrs: nounwind
447446 declare void @llvm.assume(i1 %cmp.vtables) #0