Alex Susu via llvm-dev
2016-Dec-30 23:03 UTC
[llvm-dev] Avoiding during my pass the optimization (copy propagation) of my LLVM IR code (at generation)
Hello. I'm writing an LLVM pass that is working on LLVM IR. To my surprise the following LLVM pass code generates optimized code - it does copy propagation on it. Value *vecShuffleOnePtr = Builder.CreateGEP(ptr_B, vecShuffleOne, "VectorGep"); ... packed_gather_params.push_back(vecShuffleOnePtr); CallInst *callGather = Builder.CreateCall(func_llvm_masked_gather_v128i16, packed_gather_params); callGather->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); DEBUG(dbgs() << "callGather: " << *callGather << "\n"); When running this code we get at stderr something like: callgather: %50 = call <4 x i16> @llvm.masked.gather.v4i16(<4 x i16*> getelementptr (i16, i16* inttoptr (i16 51 to i16*), <4 x i64> <i64 1, i64 1, i64 1, i64 1>), i32 0, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef) Also, more importantly, the resulting LLVM program will also contain this 1 gather LLVM IR instruction. So, although I instructed LLVM to generate 2 instructions, it creates only one instruction, a call to gather containing as parameter not the VectorGep variable name, but its value/definition, the getelementptr instruction (and this happens even if VectorGep is used more than once in my program). Is there a way to specify programmatically in my LLVM pass to avoid doing this copy propagation optimization (and obtain an LLVM program with a separate getelementptr instruction, besides the gather instruction)? Thank you, Alex
Mehdi Amini via llvm-dev
2016-Dec-31 03:20 UTC
[llvm-dev] Avoiding during my pass the optimization (copy propagation) of my LLVM IR code (at generation)
> On Dec 30, 2016, at 3:03 PM, Alex Susu via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hello. > I'm writing an LLVM pass that is working on LLVM IR. > To my surprise the following LLVM pass code generates optimized code - it does copy propagation on it.It does *constant* propagation to be exact.> Value *vecShuffleOnePtr = Builder.CreateGEP(ptr_B, vecShuffleOne, "VectorGep"); > ... > packed_gather_params.push_back(vecShuffleOnePtr); > CallInst *callGather = Builder.CreateCall(func_llvm_masked_gather_v128i16, > packed_gather_params); > callGather->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); > > DEBUG(dbgs() << "callGather: " << *callGather << "\n"); > > When running this code we get at stderr something like: > callgather: %50 = call <4 x i16> @llvm.masked.gather.v4i16(<4 x i16*> getelementptr (i16, i16* inttoptr (i16 51 to i16*), <4 x i64> <i64 1, i64 1, i64 1, i64 1>), i32 0, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef) > Also, more importantly, the resulting LLVM program will also contain this 1 gather LLVM IR instruction. > > So, although I instructed LLVM to generate 2 instructions, it creates only one instruction, a call to gather containing as parameter not the VectorGep variable name, but its value/definition, the getelementptr instruction (and this happens even if VectorGep is used more than once in my program). > > Is there a way to specify programmatically in my LLVM pass to avoid doing this copy propagation optimization (and obtain an LLVM program with a separate getelementptr instruction, besides the gather instruction)?No: you can’t really force constant to not be propagated (At least I don’t know an easy way for that). — Mehdi
Michael Kuperstein via llvm-dev
2017-Jan-01 22:10 UTC
[llvm-dev] Avoiding during my pass the optimization (copy propagation) of my LLVM IR code (at generation)
You can avoid at least some of it by using the Instruction interfaces (e.g. CallInst::Create()) directly instead of IRBuilder. But (a) I'm not sure if this will change what happens in this particular case, and (b) I would strongly suggest you not do this, though, unless you have a really good reason (you're trying to generate a specific instruction sequence for, say, fuzzing). On 30 December 2016 at 19:20, Mehdi Amini via llvm-dev < llvm-dev at lists.llvm.org> wrote:> > > On Dec 30, 2016, at 3:03 PM, Alex Susu via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > Hello. > > I'm writing an LLVM pass that is working on LLVM IR. > > To my surprise the following LLVM pass code generates optimized code > - it does copy propagation on it. > > It does *constant* propagation to be exact. > > > Value *vecShuffleOnePtr = Builder.CreateGEP(ptr_B, vecShuffleOne, > "VectorGep"); > > ... > > packed_gather_params.push_back(vecShuffleOnePtr); > > CallInst *callGather = Builder.CreateCall(func_llvm_ > masked_gather_v128i16, > > packed_gather_params); > > callGather->addAttribute(AttributeSet::FunctionIndex, > Attribute::NoUnwind); > > > > DEBUG(dbgs() << "callGather: " << *callGather << "\n"); > > > > When running this code we get at stderr something like: > > callgather: %50 = call <4 x i16> @llvm.masked.gather.v4i16(<4 x > i16*> getelementptr (i16, i16* inttoptr (i16 51 to i16*), <4 x i64> <i64 1, > i64 1, i64 1, i64 1>), i32 0, <4 x i1> <i1 true, i1 true, i1 true, i1 > true>, <4 x i16> undef) > > Also, more importantly, the resulting LLVM program will also contain > this 1 gather LLVM IR instruction. > > > > So, although I instructed LLVM to generate 2 instructions, it creates > only one instruction, a call to gather containing as parameter not the > VectorGep variable name, but its value/definition, the getelementptr > instruction (and this happens even if VectorGep is used more than once in > my program). > > > > Is there a way to specify programmatically in my LLVM pass to avoid > doing this copy propagation optimization (and obtain an LLVM program with a > separate getelementptr instruction, besides the gather instruction)? > > No: you can’t really force constant to not be propagated (At least I don’t > know an easy way for that). > > — > Mehdi > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170101/b5049b30/attachment.html>
David Chisnall via llvm-dev
2017-Jan-02 11:51 UTC
[llvm-dev] Avoiding during my pass the optimization (copy propagation) of my LLVM IR code (at generation)
On 30 Dec 2016, at 23:03, Alex Susu via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hello. > I'm writing an LLVM pass that is working on LLVM IR. > To my surprise the following LLVM pass code generates optimized code - it does copy propagation on it. > Value *vecShuffleOnePtr = Builder.CreateGEP(ptr_B, vecShuffleOne, "VectorGep"); > ... > packed_gather_params.push_back(vecShuffleOnePtr); > CallInst *callGather = Builder.CreateCall(func_llvm_masked_gather_v128i16, > packed_gather_params); > callGather->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); > > DEBUG(dbgs() << "callGather: " << *callGather << "\n"); > > When running this code we get at stderr something like: > callgather: %50 = call <4 x i16> @llvm.masked.gather.v4i16(<4 x i16*> getelementptr (i16, i16* inttoptr (i16 51 to i16*), <4 x i64> <i64 1, i64 1, i64 1, i64 1>), i32 0, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i16> undef) > Also, more importantly, the resulting LLVM program will also contain this 1 gather LLVM IR instruction. > > So, although I instructed LLVM to generate 2 instructions, it creates only one instruction, a call to gather containing as parameter not the VectorGep variable name, but its value/definition, the getelementptr instruction (and this happens even if VectorGep is used more than once in my program). > > Is there a way to specify programmatically in my LLVM pass to avoid doing this copy propagation optimization (and obtain an LLVM program with a separate getelementptr instruction, besides the gather instruction)?You seem to be experiencing some confusion related to the difference between instructions and constant expressions. A number of IR expressions (e.g. GEPs, ptrtoint, inttoptr), which do not have side effects, can be expressed in one of two ways: instructions, which are intended to represent dynamic values, which depend on their inputs, and constant expressions. Constant expressions are equivalent to instructions, but are only valid when the inputs are also constant. When you ask IRBuilder for a GEP, it will give you either a GetElementPtrConstantExpr or a GetElementPtrInst, depending on whether the inputs are also constant expressions. If you don’t want this behaviour, then you can construct a GetElementPtrInst yourself directly, but this is generally a bad idea: early optimisations will turn the GetElementPtrInst into a GetElementPtrConstantExpr and you’re making the fact that the GEP is a compile-time constant harder to determine for anything else looking at the IR. David