Xiangyang Guo via llvm-dev
2016-Mar-24 19:45 UTC
[llvm-dev] attribute of intrinsic function
Hi, When I define an intrinsic function with memory write permission, my assumption is that we can either attach [IntrReadWriteArgMem] or [] to the intrinsic function. Based on the comment of the source code , "IntrReadWriteArgMem - This intrinsic reads and writes only from memory that one of its arguments points to, but may access an unspecified amount." "If no property is set, the worst case is assumed (it may read and write any memory it can get access to and it may have other side effects)". But when I define the intrinsic function with different attributes, there is no difference when I dump the IR. For example, two intrinsic functions are def int_foo5 : Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>; def int_foo6 : Intrinsic<[], [llvm_ptr_ty], []>; Then I write a very simple module, in each module the intrinsic function is called twice as shown below: /******the intrinsic function foo5 is used******/ ; Function Attrs: nounwind define void @_Z3fooPi(i8* %a) #0 { call void @llvm.foo5(i8* %a) call void @llvm.foo5(i8* %a) ret void } ; Function Attrs: nounwind declare void @llvm.foo5(i8*) #0 attributes #0 = { nounwind } /****** the intrinsic function foo6 is used******/ ; Function Attrs: nounwind define void @_Z3fooPi(i8* %a) #0 { call void @llvm.foo6(i8* %a) call void @llvm.foo6(i8* %a) ret void } ; Function Attrs: nounwind declare void @llvm.foo6(i8*) #0 attributes #0 = { nounwind } And my when I apply -O3 optimization level for these two bitcode, I hope the second call can be eliminated. But from the result, it doesn't. For intrinsic functio foo5, I don't understand it. I mean, when I apply [IntrReadWriteArgMem] to this intrinsic function, I hope the LLVM can know the second one is redundant because nothing is changed. Can you tell why LLVM cannot optimize it in this case? Any input is appreciable. Regards, Xiangyang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160324/6f2c51ca/attachment.html>
> On Mar 24, 2016, at 12:45 PM, Xiangyang Guo via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi, > > When I define an intrinsic function with memory write permission, my assumption is that we can either attach [IntrReadWriteArgMem] or [] to the intrinsic function. Based on the comment of the source code , "IntrReadWriteArgMem - This intrinsic reads and writes only from memory that one of its arguments points to, but may access an unspecified amount." "If no property is set, the worst case is assumed (it may read and write any memory it can get access to and it may have other side effects)". > > But when I define the intrinsic function with different attributes, there is no difference when I dump the IR. For example, two intrinsic functions are > > def int_foo5 : Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>; > def int_foo6 : Intrinsic<[], [llvm_ptr_ty], []>; > > Then I write a very simple module, in each module the intrinsic function is called twice as shown below: > > /******the intrinsic function foo5 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo5(i8* %a) > call void @llvm.foo5(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo5(i8*) #0 > attributes #0 = { nounwind }I'd expect foo4 to have the "argmemonly" attribute. How did you generate this IR? If you round-trip to bitcode, what happens? I expect the attribute to be added. -- Mehdi> > > /****** the intrinsic function foo6 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo6(i8* %a) > call void @llvm.foo6(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo6(i8*) #0 > attributes #0 = { nounwind } > > And my when I apply -O3 optimization level for these two bitcode, I hope the second call can be eliminated. But from the result, it doesn't. For intrinsic functio foo5, I don't understand it. I mean, when I apply [IntrReadWriteArgMem] to this intrinsic function, I hope the LLVM can know the second one is redundant because nothing is changed. Can you tell why LLVM cannot optimize it in this case? > > Any input is appreciable. > > Regards, > > Xiangyang > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Xiangyang Guo via llvm-dev
2016-Mar-24 21:07 UTC
[llvm-dev] attribute of intrinsic function
Hi, Mehdi, I use the following code to generate the IR: * std::vector<Type *> arg_type;* * std::vector<Value *> margs;* * margs.push_back(ptr_a);* * callee = Intrinsic::getDeclaration(mod, Intrinsic::foo5, arg_type);* * Value *dest_value = Builder.CreateCall(callee, margs);* * Value *dest_value1 = Builder.CreateCall(callee, margs);* And even if I add the 'argmemonly' manually, it does not help. The problems come from two places: (1) when I use the following code to add the attribute, the attribute is not there in the bit code. Maybe it's because the intrinsic function can only have one attribute? * AttributeSet func__Z3fooPi_PAL;* * {* * SmallVector<AttributeSet, 4> Attrs;* * AttributeSet PAS;* * {* * AttrBuilder B;* * B.addAttribute(Attribute::NoUnwind);* * B.addAttribute(Attribute::ArgMemOnly);* * PAS = AttributeSet::get(mod->getContext(), ~0U, B);* * }* * Attrs.push_back(PAS);* * func__Z3fooPi_PAL = AttributeSet::get(mod->getContext(), Attrs);* * }* *// this is the new bitcode* ; Function Attrs: nounwind argmemonly define void @_Z3fooPi(i8* %a) #0 { call void @llvm.foo5(i8* %a) call void @llvm.foo5(i8* %a) ret void } ; Function Attrs: nounwind declare void @llvm.foo5(i8*) #1 attributes #0 = { nounwind argmemonly } attributes #1 = { nounwind } (2) when I change the .ll file to add argmemonly'' manually, it does not work either. Ane idea? Thanks, Xiangyang 2016-03-24 13:12 GMT-07:00 Mehdi Amini <mehdi.amini at apple.com>:> > > On Mar 24, 2016, at 12:45 PM, Xiangyang Guo via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > Hi, > > > > When I define an intrinsic function with memory write permission, my > assumption is that we can either attach [IntrReadWriteArgMem] or [] to the > intrinsic function. Based on the comment of the source code , > "IntrReadWriteArgMem - This intrinsic reads and writes only from memory > that one of its arguments points to, but may access an unspecified amount." > "If no property is set, the worst case is assumed (it may read and write > any memory it can get access to and it may have other side effects)". > > > > But when I define the intrinsic function with different attributes, > there is no difference when I dump the IR. For example, two intrinsic > functions are > > > > def int_foo5 : Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>; > > def int_foo6 : Intrinsic<[], [llvm_ptr_ty], []>; > > > > Then I write a very simple module, in each module the intrinsic function > is called twice as shown below: > > > > /******the intrinsic function foo5 is used******/ > > ; Function Attrs: nounwind > > define void @_Z3fooPi(i8* %a) #0 { > > call void @llvm.foo5(i8* %a) > > call void @llvm.foo5(i8* %a) > > ret void > > } > > ; Function Attrs: nounwind > > declare void @llvm.foo5(i8*) #0 > > attributes #0 = { nounwind } > > I'd expect foo4 to have the "argmemonly" attribute. > How did you generate this IR? > If you round-trip to bitcode, what happens? I expect the attribute to be > added. > > -- > Mehdi > > > > > > > > > /****** the intrinsic function foo6 is used******/ > > ; Function Attrs: nounwind > > define void @_Z3fooPi(i8* %a) #0 { > > call void @llvm.foo6(i8* %a) > > call void @llvm.foo6(i8* %a) > > ret void > > } > > ; Function Attrs: nounwind > > declare void @llvm.foo6(i8*) #0 > > attributes #0 = { nounwind } > > > > And my when I apply -O3 optimization level for these two bitcode, I hope > the second call can be eliminated. But from the result, it doesn't. For > intrinsic functio foo5, I don't understand it. I mean, when I apply > [IntrReadWriteArgMem] to this intrinsic function, I hope the LLVM can know > the second one is redundant because nothing is changed. Can you tell why > LLVM cannot optimize it in this case? > > > > Any input is appreciable. > > > > Regards, > > > > Xiangyang > > > > > > _______________________________________________ > > 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/20160324/b3d5cd38/attachment.html>
Philip Reames via llvm-dev
2016-Mar-24 21:30 UTC
[llvm-dev] attribute of intrinsic function
On 03/24/2016 12:45 PM, Xiangyang Guo via llvm-dev wrote:> Hi, > > When I define an intrinsic function with memory write permission, my > assumption is that we can either attach [IntrReadWriteArgMem] or [] to > the intrinsic function. Based on the comment of the source code , > "IntrReadWriteArgMem - This intrinsic reads and writes only from > memory that one of its arguments points to, but may access an > unspecified amount." "If no property is set, the worst case is assumed > (it may read and write any memory it can get access to and it may have > other side effects)". > > But when I define the intrinsic function with different attributes, > there is no difference when I dump the IR. For example, two intrinsic > functions are > > def int_foo5 : Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>; > def int_foo6 : Intrinsic<[], [llvm_ptr_ty], []>; > > Then I write a very simple module, in each module the intrinsic > function is called twice as shown below: > > /******the intrinsic function foo5 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo5(i8* %a) > call void @llvm.foo5(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo5(i8*) #0 > attributes #0 = { nounwind }This is strange. I would expect this to introduce the argmemonly attribute. Can you confirm that you're on tip-of-tree and not some previous LLVM release version?> > > /****** the intrinsic function foo6 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo6(i8* %a) > call void @llvm.foo6(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo6(i8*) #0 > attributes #0 = { nounwind } > > And my when I apply -O3 optimization level for these two bitcode, I > hope the second call can be eliminated. But from the result, it doesn't.Removing the previous call would be an incorrect optimization. Specifically, the intrinsic "foo5" could be an increment of the passed memory location. Removing one of the two increments would be incorrect. I suspect you actually know something stronger about the intrinsic. Is it possible readonly? Or write only? Or idempotent? Or something else?> For intrinsic functio foo5, I don't understand it. I mean, when I > apply [IntrReadWriteArgMem] to this intrinsic function, I hope the > LLVM can know the second one is redundant because nothing is changed. > Can you tell why LLVM cannot optimize it in this case? > > Any input is appreciable. > > Regards, > > Xiangyang > > > > > _______________________________________________ > 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/20160324/36a102c3/attachment.html>
Xiangyang Guo via llvm-dev
2016-Mar-25 15:00 UTC
[llvm-dev] attribute of intrinsic function
Thanks for your reply, Philip. You are right, when I use LLVM-3.8, the 'argmemonly' shows up. Previously, I use LLVM-3.7. I think idempotent is what I want. Can you tell me how to add idempotent attribute to the function? Thanks. Regards, Xiangyang 2016-03-24 14:30 GMT-07:00 Philip Reames <listmail at philipreames.com>:> > > On 03/24/2016 12:45 PM, Xiangyang Guo via llvm-dev wrote: > > Hi, > > When I define an intrinsic function with memory write permission, my > assumption is that we can either attach [IntrReadWriteArgMem] or [] to the > intrinsic function. Based on the comment of the source code , > "IntrReadWriteArgMem - This intrinsic reads and writes only from memory > that one of its arguments points to, but may access an unspecified amount." > "If no property is set, the worst case is assumed (it may read and write > any memory it can get access to and it may have other side effects)". > > But when I define the intrinsic function with different attributes, there > is no difference when I dump the IR. For example, two intrinsic functions > are > > def int_foo5 : Intrinsic<[], [llvm_ptr_ty], [IntrReadWriteArgMem]>; > def int_foo6 : Intrinsic<[], [llvm_ptr_ty], []>; > > Then I write a very simple module, in each module the intrinsic function > is called twice as shown below: > > /******the intrinsic function foo5 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo5(i8* %a) > call void @llvm.foo5(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo5(i8*) #0 > attributes #0 = { nounwind } > > This is strange. I would expect this to introduce the argmemonly > attribute. Can you confirm that you're on tip-of-tree and not some > previous LLVM release version? > > > > /****** the intrinsic function foo6 is used******/ > ; Function Attrs: nounwind > define void @_Z3fooPi(i8* %a) #0 { > call void @llvm.foo6(i8* %a) > call void @llvm.foo6(i8* %a) > ret void > } > ; Function Attrs: nounwind > declare void @llvm.foo6(i8*) #0 > attributes #0 = { nounwind } > > And my when I apply -O3 optimization level for these two bitcode, I hope > the second call can be eliminated. But from the result, it doesn't. > > Removing the previous call would be an incorrect optimization. > Specifically, the intrinsic "foo5" could be an increment of the passed > memory location. Removing one of the two increments would be incorrect. > > I suspect you actually know something stronger about the intrinsic. Is it > possible readonly? Or write only? Or idempotent? Or something else? > > For intrinsic functio foo5, I don't understand it. I mean, when I apply > [IntrReadWriteArgMem] to this intrinsic function, I hope the LLVM can know > the second one is redundant because nothing is changed. Can you tell why > LLVM cannot optimize it in this case? > > Any input is appreciable. > > Regards, > > Xiangyang > > > > > _______________________________________________ > LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://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/20160325/11cefc73/attachment.html>