[PATCH] D47103: Implement strip.invariant.group
This revision was automatically updated to reflect the committed changes. Prazek marked an inline comment as done. Closed by commit rL336073: Implement strip.invariant.group (authored by Prazek, committed by ). Changed prior to commit: https://reviews.llvm.org/D47103?vs=148313=153664#toc Repository: rL LLVM https://reviews.llvm.org/D47103 Files: llvm/trunk/docs/LangRef.rst llvm/trunk/include/llvm/IR/IRBuilder.h llvm/trunk/include/llvm/IR/Intrinsics.td llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/IR/Value.cpp llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/trunk/test/Analysis/ValueTracking/invariant.group.ll llvm/trunk/test/CodeGen/Generic/intrinsics.ll llvm/trunk/test/Other/invariant.group.ll llvm/trunk/test/Other/launder.invariant.group.ll llvm/trunk/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/trunk/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll llvm/trunk/test/Transforms/GVN/invariant.group.ll llvm/trunk/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/trunk/test/Transforms/GlobalOpt/invariant.group.ll llvm/trunk/test/Transforms/InstCombine/invariant.group.ll llvm/trunk/test/Transforms/NewGVN/invariant.group.ll Index: llvm/trunk/lib/IR/Value.cpp === --- llvm/trunk/lib/IR/Value.cpp +++ llvm/trunk/lib/IR/Value.cpp @@ -521,7 +521,8 @@ // but it can't be marked with returned attribute, that's why it needs // special case. if (StripKind == PSK_ZeroIndicesAndAliasesAndInvariantGroups && -CS.getIntrinsicID() == Intrinsic::launder_invariant_group) { +(CS.getIntrinsicID() == Intrinsic::launder_invariant_group || + CS.getIntrinsicID() == Intrinsic::strip_invariant_group)) { V = CS.getArgOperand(0); continue; } Index: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp === --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1437,6 +1437,7 @@ return true; } case Intrinsic::launder_invariant_group: + case Intrinsic::strip_invariant_group: case Intrinsic::expect: { unsigned ResultReg = getRegForValue(II->getArgOperand(0)); if (!ResultReg) Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp === --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5768,6 +5768,7 @@ case Intrinsic::annotation: case Intrinsic::ptr_annotation: case Intrinsic::launder_invariant_group: + case Intrinsic::strip_invariant_group: // Drop the intrinsic, but forward the value setValue(, getValue(I.getOperand(0))); return nullptr; Index: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp === --- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp @@ -1702,6 +1702,7 @@ return true; } case Intrinsic::launder_invariant_group: +case Intrinsic::strip_invariant_group: II->replaceAllUsesWith(II->getArgOperand(0)); II->eraseFromParent(); return true; Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp === --- llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -457,6 +457,7 @@ case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::launder_invariant_group: + case Intrinsic::strip_invariant_group: case Intrinsic::objectsize: return true; default: @@ -882,6 +883,7 @@ case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::launder_invariant_group: +case Intrinsic::strip_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: llvm/trunk/lib/Analysis/ValueTracking.cpp === --- llvm/trunk/lib/Analysis/ValueTracking.cpp +++ llvm/trunk/lib/Analysis/ValueTracking.cpp @@ -3404,8 +3404,9 @@ } bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( - ImmutableCallSite CS) { - return CS.getIntrinsicID() == Intrinsic::launder_invariant_group; +ImmutableCallSite CS) { + return CS.getIntrinsicID() ==
[PATCH] D47103: Implement strip.invariant.group
rsmith accepted this revision. rsmith added inline comments. This revision is now accepted and ready to land. Comment at: llvm/docs/LangRef.rst:12928 +established by ``invariant.group`` metadata no longer holds, to obtain a new pointer +value that does carries fresh invariant group information. It is an experimental intrinsic, which means that its semantics might change in the future. does carries -> carries Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
Prazek added a comment. Friendly ping @hfinkel @rsmith Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
Prazek added a comment. friendly ping Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
rjmccall added inline comments. Comment at: clang/lib/CodeGen/CGExpr.cpp:3858 +} + } + Prazek wrote: > rjmccall wrote: > > Please add a comment explaining why this is necessary. (I'm actually not > > sure why it is, because surely the invariant groups we generate don't > > contain assumptions about memory from fields, right?) > Short answer: you can only make virtual calls on a dynamic pointer that > carries invariant.group and you can't do anything other because it could leak > the information about this pointer (which when used with comparison could > break devirtualization). Alright, sure. Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
Prazek updated this revision to Diff 148313. Prazek marked 2 inline comments as done. Prazek added a comment. Slitted commit into defining and using intrinsic Repository: rL LLVM https://reviews.llvm.org/D47103 Files: llvm/docs/LangRef.rst llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/BasicAliasAnalysis.cpp llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/Value.cpp llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/test/Analysis/ValueTracking/invariant.group.ll llvm/test/CodeGen/Generic/intrinsics.ll llvm/test/Other/invariant.group.ll llvm/test/Other/launder.invariant.group.ll llvm/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/test/Transforms/FunctionAttrs/nocapture.ll llvm/test/Transforms/GVN/invariant.group.ll llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/test/Transforms/GlobalOpt/invariant.group.ll llvm/test/Transforms/InstCombine/invariant.group.ll llvm/test/Transforms/NewGVN/invariant.group.ll Index: llvm/test/Transforms/NewGVN/invariant.group.ll === --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -52,6 +52,19 @@ ret i8 %b } +; CHECK-LABEL: define i1 @proveEqualityForStrip( +define i1 @proveEqualityForStrip(i8* %a) { +; FIXME: The first call could be also removed by GVN. Right now +; DCE removes it. The second call is CSE'd with the first one. +; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) +; CHECK-NOT: llvm.strip.invariant.group + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %r = icmp eq i8* %b1, %b2 +; CHECK: ret i1 true + ret i1 %r +} + ; CHECK-LABEL: define i8 @unoptimizable1() { define i8 @unoptimizable1() { entry: Index: llvm/test/Transforms/InstCombine/invariant.group.ll === --- llvm/test/Transforms/InstCombine/invariant.group.ll +++ llvm/test/Transforms/InstCombine/invariant.group.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s + ; CHECK-LABEL: define i8* @simplifyNullLaunder() define i8* @simplifyNullLaunder() { ; CHECK-NEXT: ret i8* null @@ -29,6 +30,39 @@ ret i8 addrspace(42)* %b2 } - declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*) + + +; CHECK-LABEL: define i8* @simplifyNullStrip() +define i8* @simplifyNullStrip() { +; CHECK-NEXT: ret i8* null + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() +define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() { +; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) +; CHECK: ret i8 addrspace(42)* %b2 + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) + ret i8 addrspace(42)* %b2 +} + +; CHECK-LABEL: define i8* @simplifyUndefStrip() +define i8* @simplifyUndefStrip() { +; CHECK-NEXT: ret i8* undef + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2() +define i8 addrspace(42)* @simplifyUndefStrip2() { +; CHECK-NEXT: ret i8 addrspace(42)* undef + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef) + ret i8 addrspace(42)* %b2 +} + +declare i8* @llvm.strip.invariant.group.p0i8(i8*) +declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*) + Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll === --- llvm/test/Transforms/GlobalOpt/invariant.group.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.ll @@ -27,46 +27,46 @@ define void @_optimizable() { enter: %valptr = alloca i32 - + %val = call i32 @TheAnswerToLifeTheUniverseAndEverything() store i32 %val, i32* @tmp store i32 %val, i32* %valptr - + %0 = bitcast i32* %valptr to i8* %barr = call i8* @llvm.launder.invariant.group(i8* %0) %1 = bitcast i8* %barr to i32* - + %val2 = load i32, i32* %1 store i32 %val2, i32* @tmp2 ret void } ; 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 +; val = load i32, i32* %ptrVal, !invariant.group !0 +; into ; %val = load i32, i32* @tmp3, !invariant.group !0 -; and then we could assume that %val and %val2 to be the same,
[PATCH] D47103: Implement strip.invariant.group
Prazek added inline comments. Comment at: clang/lib/CodeGen/CGExpr.cpp:3858 +} + } + rjmccall wrote: > Please add a comment explaining why this is necessary. (I'm actually not > sure why it is, because surely the invariant groups we generate don't contain > assumptions about memory from fields, right?) Short answer: you can only make virtual calls on a dynamic pointer that carries invariant.group and you can't do anything other because it could leak the information about this pointer (which when used with comparison could break devirtualization). Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
rjmccall added a comment. The changes to Clang generally seem reasonable, but I think you should split them into a separate commit from the commit that adds the intrinsic itself. Comment at: clang/lib/CodeGen/CGExpr.cpp:3858 +} + } + Please add a comment explaining why this is necessary. (I'm actually not sure why it is, because surely the invariant groups we generate don't contain assumptions about memory from fields, right?) Comment at: clang/lib/CodeGen/CGExprScalar.cpp:1626 + Src = Builder.CreateStripInvariantGroup(Src); +} + Again, comment. Comment at: clang/lib/CodeGen/CGExprScalar.cpp:1767 +if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) + return Builder.CreateLaunderInvariantGroup(IntToPtr); + I think assigning to IntToPtr would be clearer here. You're changing the value returned, not introducing a reason to early-exit. And a comment, please, on all of these cases. Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
amharc added inline comments. Comment at: clang/include/clang/AST/DeclCXX.h:778 + bool mayBeDynamicClass() const { +return !isCompleteDefinition() || isDynamicClass(); xbolva00 wrote: > maybeDynamicClass? > > https://github.com/llvm-mirror/llvm/search?utf8=%E2%9C%93=maybe= I think `mayBe` is more appropriate, because it grammatically consists of 'may' and 'be'. In this form it appears in multiple places in the codebase, too. A few examples: https://github.com/llvm-mirror/llvm/blob/0b24b74655b976aaba01b2f726659b8c745a16de/include/llvm/IR/GlobalValue.h#L131 https://github.com/llvm-mirror/clang/blob/647be32c6048e24f90f470c557e850597e5526c3/lib/AST/DeclCXX.cpp#L1800 https://github.com/llvm-mirror/llvm/blob/77438c3c98c0901fa9ef56f78bdefccedc16fcc4/lib/Analysis/ValueTracking.cpp#L3659 Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
Prazek updated this revision to Diff 147691. Prazek added a comment. rebase Repository: rL LLVM https://reviews.llvm.org/D47103 Files: clang/include/clang/AST/DeclCXX.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/test/CodeGenCXX/strict-vtable-pointers.cpp llvm/docs/LangRef.rst llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/BasicAliasAnalysis.cpp llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/Value.cpp llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/test/Analysis/ValueTracking/invariant.group.ll llvm/test/CodeGen/Generic/intrinsics.ll llvm/test/Other/invariant.group.ll llvm/test/Other/launder.invariant.group.ll llvm/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/test/Transforms/FunctionAttrs/nocapture.ll llvm/test/Transforms/GVN/invariant.group.ll llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/test/Transforms/GlobalOpt/invariant.group.ll llvm/test/Transforms/InstCombine/invariant.group.ll llvm/test/Transforms/NewGVN/invariant.group.ll Index: llvm/test/Transforms/NewGVN/invariant.group.ll === --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -52,6 +52,19 @@ ret i8 %b } +; CHECK-LABEL: define i1 @proveEqualityForStrip( +define i1 @proveEqualityForStrip(i8* %a) { +; FIXME: The first call could be also removed by GVN. Right now +; DCE removes it. The second call is CSE'd with the first one. +; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) +; CHECK-NOT: llvm.strip.invariant.group + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %r = icmp eq i8* %b1, %b2 +; CHECK: ret i1 true + ret i1 %r +} + ; CHECK-LABEL: define i8 @unoptimizable1() { define i8 @unoptimizable1() { entry: Index: llvm/test/Transforms/InstCombine/invariant.group.ll === --- llvm/test/Transforms/InstCombine/invariant.group.ll +++ llvm/test/Transforms/InstCombine/invariant.group.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s + ; CHECK-LABEL: define i8* @simplifyNullLaunder() define i8* @simplifyNullLaunder() { ; CHECK-NEXT: ret i8* null @@ -29,6 +30,39 @@ ret i8 addrspace(42)* %b2 } - declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*) + + +; CHECK-LABEL: define i8* @simplifyNullStrip() +define i8* @simplifyNullStrip() { +; CHECK-NEXT: ret i8* null + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() +define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() { +; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) +; CHECK: ret i8 addrspace(42)* %b2 + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) + ret i8 addrspace(42)* %b2 +} + +; CHECK-LABEL: define i8* @simplifyUndefStrip() +define i8* @simplifyUndefStrip() { +; CHECK-NEXT: ret i8* undef + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2() +define i8 addrspace(42)* @simplifyUndefStrip2() { +; CHECK-NEXT: ret i8 addrspace(42)* undef + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef) + ret i8 addrspace(42)* %b2 +} + +declare i8* @llvm.strip.invariant.group.p0i8(i8*) +declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*) + Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll === --- llvm/test/Transforms/GlobalOpt/invariant.group.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.ll @@ -27,46 +27,46 @@ define void @_optimizable() { enter: %valptr = alloca i32 - + %val = call i32 @TheAnswerToLifeTheUniverseAndEverything() store i32 %val, i32* @tmp store i32 %val, i32* %valptr - + %0 = bitcast i32* %valptr to i8* %barr = call i8* @llvm.launder.invariant.group(i8* %0) %1 = bitcast i8* %barr to i32* - + %val2 = load i32, i32* %1 store i32 %val2, i32* @tmp2 ret void } ; 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 +; val = load i32, i32* %ptrVal, !invariant.group !0 +; into ; %val = load i32, i32* @tmp3, !invariant.group
[PATCH] D47103: Implement strip.invariant.group
Prazek updated this revision to Diff 147688. Prazek added a comment. After rebasing Repository: rL LLVM https://reviews.llvm.org/D47103 Files: clang/include/clang/AST/DeclCXX.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/test/CodeGenCXX/strict-vtable-pointers.cpp llvm/docs/LangRef.rst llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/BasicAliasAnalysis.cpp llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/Value.cpp llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/test/Analysis/ValueTracking/invariant.group.ll llvm/test/CodeGen/Generic/intrinsics.ll llvm/test/Other/invariant.group.ll llvm/test/Other/launder.invariant.group.ll llvm/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/test/Transforms/FunctionAttrs/nocapture.ll llvm/test/Transforms/GVN/invariant.group.ll llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/test/Transforms/GlobalOpt/invariant.group.ll llvm/test/Transforms/InstCombine/invariant.group.ll llvm/test/Transforms/NewGVN/invariant.group.ll Index: llvm/test/Transforms/NewGVN/invariant.group.ll === --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -52,6 +52,19 @@ ret i8 %b } +; CHECK-LABEL: define i1 @proveEqualityForStrip( +define i1 @proveEqualityForStrip(i8* %a) { +; FIXME: The first call could be also removed by GVN. Right now +; DCE removes it. The second call is CSE'd with the first one. +; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) +; CHECK-NOT: llvm.strip.invariant.group + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %r = icmp eq i8* %b1, %b2 +; CHECK: ret i1 true + ret i1 %r +} + ; CHECK-LABEL: define i8 @unoptimizable1() { define i8 @unoptimizable1() { entry: Index: llvm/test/Transforms/InstCombine/invariant.group.ll === --- llvm/test/Transforms/InstCombine/invariant.group.ll +++ llvm/test/Transforms/InstCombine/invariant.group.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s + ; CHECK-LABEL: define i8* @simplifyNullLaunder() define i8* @simplifyNullLaunder() { ; CHECK-NEXT: ret i8* null @@ -29,6 +30,39 @@ ret i8 addrspace(42)* %b2 } - declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*) + + +; CHECK-LABEL: define i8* @simplifyNullStrip() +define i8* @simplifyNullStrip() { +; CHECK-NEXT: ret i8* null + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() +define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() { +; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) +; CHECK: ret i8 addrspace(42)* %b2 + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) + ret i8 addrspace(42)* %b2 +} + +; CHECK-LABEL: define i8* @simplifyUndefStrip() +define i8* @simplifyUndefStrip() { +; CHECK-NEXT: ret i8* undef + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2() +define i8 addrspace(42)* @simplifyUndefStrip2() { +; CHECK-NEXT: ret i8 addrspace(42)* undef + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef) + ret i8 addrspace(42)* %b2 +} + +declare i8* @llvm.strip.invariant.group.p0i8(i8*) +declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*) + Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll === --- llvm/test/Transforms/GlobalOpt/invariant.group.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.ll @@ -27,46 +27,46 @@ define void @_optimizable() { enter: %valptr = alloca i32 - + %val = call i32 @TheAnswerToLifeTheUniverseAndEverything() store i32 %val, i32* @tmp store i32 %val, i32* %valptr - + %0 = bitcast i32* %valptr to i8* %barr = call i8* @llvm.launder.invariant.group(i8* %0) %1 = bitcast i8* %barr to i32* - + %val2 = load i32, i32* %1 store i32 %val2, i32* @tmp2 ret void } ; 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 +; val = load i32, i32* %ptrVal, !invariant.group !0 +; into ; %val = load i32, i32* @tmp3,
[PATCH] D47103: Implement strip.invariant.group
Prazek updated this revision to Diff 147684. Prazek added a comment. Changed comments Repository: rL LLVM https://reviews.llvm.org/D47103 Files: clang/include/clang/AST/DeclCXX.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/test/CodeGenCXX/strict-vtable-pointers.cpp llvm/docs/LangRef.rst llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/BasicAliasAnalysis.cpp llvm/lib/Analysis/CaptureTracking.cpp llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/Value.cpp llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/test/Analysis/ValueTracking/invariant.group.ll llvm/test/CodeGen/Generic/intrinsics.ll llvm/test/Other/invariant.group.ll llvm/test/Other/launder.invariant.group.ll llvm/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/test/Transforms/FunctionAttrs/nocapture.ll llvm/test/Transforms/GVN/invariant.group.ll llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/test/Transforms/GlobalOpt/invariant.group.ll llvm/test/Transforms/InstCombine/invariant.group.ll llvm/test/Transforms/NewGVN/invariant.group.ll Index: llvm/test/Transforms/NewGVN/invariant.group.ll === --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -52,6 +52,19 @@ ret i8 %b } +; CHECK-LABEL: define i1 @proveEqualityForStrip( +define i1 @proveEqualityForStrip(i8* %a) { +; FIXME: The first call could be also removed by GVN. Right now +; DCE removes it. The second call is CSE'd with the first one. +; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) +; CHECK-NOT: llvm.strip.invariant.group + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %r = icmp eq i8* %b1, %b2 +; CHECK: ret i1 true + ret i1 %r +} + ; CHECK-LABEL: define i8 @unoptimizable1() { define i8 @unoptimizable1() { entry: Index: llvm/test/Transforms/InstCombine/invariant.group.ll === --- llvm/test/Transforms/InstCombine/invariant.group.ll +++ llvm/test/Transforms/InstCombine/invariant.group.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s + ; CHECK-LABEL: define i8* @simplifyNullLaunder() define i8* @simplifyNullLaunder() { ; CHECK-NEXT: ret i8* null @@ -29,6 +30,39 @@ ret i8 addrspace(42)* %b2 } - declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*) + + +; CHECK-LABEL: define i8* @simplifyNullStrip() +define i8* @simplifyNullStrip() { +; CHECK-NEXT: ret i8* null + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() +define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() { +; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) +; CHECK: ret i8 addrspace(42)* %b2 + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) + ret i8 addrspace(42)* %b2 +} + +; CHECK-LABEL: define i8* @simplifyUndefStrip() +define i8* @simplifyUndefStrip() { +; CHECK-NEXT: ret i8* undef + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2() +define i8 addrspace(42)* @simplifyUndefStrip2() { +; CHECK-NEXT: ret i8 addrspace(42)* undef + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef) + ret i8 addrspace(42)* %b2 +} + +declare i8* @llvm.strip.invariant.group.p0i8(i8*) +declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*) + Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll === --- llvm/test/Transforms/GlobalOpt/invariant.group.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.ll @@ -27,46 +27,46 @@ define void @_optimizable() { enter: %valptr = alloca i32 - + %val = call i32 @TheAnswerToLifeTheUniverseAndEverything() store i32 %val, i32* @tmp store i32 %val, i32* %valptr - + %0 = bitcast i32* %valptr to i8* %barr = call i8* @llvm.launder.invariant.group(i8* %0) %1 = bitcast i8* %barr to i32* - + %val2 = load i32, i32* %1 store i32 %val2, i32* @tmp2 ret void } ; 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 +; val = load i32, i32* %ptrVal, !invariant.group !0 +;
[PATCH] D47103: Implement strip.invariant.group
xbolva00 added inline comments. Comment at: clang/include/clang/AST/DeclCXX.h:778 + bool mayBeDynamicClass() const { +return !isCompleteDefinition() || isDynamicClass(); maybeDynamicClass? https://github.com/llvm-mirror/llvm/search?utf8=%E2%9C%93=maybe= Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47103: Implement strip.invariant.group
Prazek updated this revision to Diff 147683. Prazek added a comment. introduced mayBeDynamicClass and added more tests Repository: rL LLVM https://reviews.llvm.org/D47103 Files: clang/include/clang/AST/DeclCXX.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/test/CodeGenCXX/strict-vtable-pointers.cpp llvm/docs/LangRef.rst llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/Analysis/CaptureTracking.cpp llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/IR/Value.cpp llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp llvm/test/Analysis/ValueTracking/invariant.group.ll llvm/test/CodeGen/Generic/intrinsics.ll llvm/test/Other/invariant.group.ll llvm/test/Other/launder.invariant.group.ll llvm/test/Transforms/CodeGenPrepare/invariant.group.ll llvm/test/Transforms/DeadStoreElimination/launder.invariant.group.ll llvm/test/Transforms/FunctionAttrs/nocapture.ll llvm/test/Transforms/GVN/invariant.group.ll llvm/test/Transforms/GlobalOpt/invariant.group.barrier.ll llvm/test/Transforms/GlobalOpt/invariant.group.ll llvm/test/Transforms/InstCombine/invariant.group.ll llvm/test/Transforms/NewGVN/invariant.group.ll Index: llvm/test/Transforms/NewGVN/invariant.group.ll === --- llvm/test/Transforms/NewGVN/invariant.group.ll +++ llvm/test/Transforms/NewGVN/invariant.group.ll @@ -52,6 +52,19 @@ ret i8 %b } +; CHECK-LABEL: define i1 @proveEqualityForStrip( +define i1 @proveEqualityForStrip(i8* %a) { +; FIXME: The first call could be also removed by GVN. Right now +; DCE removes it. The second call is CSE'd with the first one. +; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) +; CHECK-NOT: llvm.strip.invariant.group + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a) + %r = icmp eq i8* %b1, %b2 +; CHECK: ret i1 true + ret i1 %r +} + ; CHECK-LABEL: define i8 @unoptimizable1() { define i8 @unoptimizable1() { entry: Index: llvm/test/Transforms/InstCombine/invariant.group.ll === --- llvm/test/Transforms/InstCombine/invariant.group.ll +++ llvm/test/Transforms/InstCombine/invariant.group.ll @@ -1,5 +1,6 @@ ; RUN: opt -instcombine -S < %s | FileCheck %s + ; CHECK-LABEL: define i8* @simplifyNullLaunder() define i8* @simplifyNullLaunder() { ; CHECK-NEXT: ret i8* null @@ -29,6 +30,39 @@ ret i8 addrspace(42)* %b2 } - declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*) + + +; CHECK-LABEL: define i8* @simplifyNullStrip() +define i8* @simplifyNullStrip() { +; CHECK-NEXT: ret i8* null + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() +define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() { +; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) +; CHECK: ret i8 addrspace(42)* %b2 + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null) + ret i8 addrspace(42)* %b2 +} + +; CHECK-LABEL: define i8* @simplifyUndefStrip() +define i8* @simplifyUndefStrip() { +; CHECK-NEXT: ret i8* undef + %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef) + ret i8* %b2 +} + +; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2() +define i8 addrspace(42)* @simplifyUndefStrip2() { +; CHECK-NEXT: ret i8 addrspace(42)* undef + %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef) + ret i8 addrspace(42)* %b2 +} + +declare i8* @llvm.strip.invariant.group.p0i8(i8*) +declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*) + Index: llvm/test/Transforms/GlobalOpt/invariant.group.ll === --- llvm/test/Transforms/GlobalOpt/invariant.group.ll +++ llvm/test/Transforms/GlobalOpt/invariant.group.ll @@ -27,46 +27,46 @@ define void @_optimizable() { enter: %valptr = alloca i32 - + %val = call i32 @TheAnswerToLifeTheUniverseAndEverything() store i32 %val, i32* @tmp store i32 %val, i32* %valptr - + %0 = bitcast i32* %valptr to i8* %barr = call i8* @llvm.launder.invariant.group(i8* %0) %1 = bitcast i8* %barr to i32* - + %val2 = load i32, i32* %1 store i32 %val2, i32* @tmp2 ret void } ; 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 +; val = load i32, i32* %ptrVal, !invariant.group !0 +; into ; %val