Dinar Temirbulatov via llvm-dev
2017-Sep-12 07:54 UTC
[llvm-dev] RFC phantom memory intrinsic
Hi, For PR21780 solution, I plan to add a new functionality to restore memory operations that was once deleted, in this particular case it is the load operations that were deleted by InstCombine, please note that once the load was removed there is no way to restore it back and that prevents us from vectorizing the shuffle operation. There are probably more similar issues where this approach could be applied. I added phatom_mem(llvm_anyptr_ty, llvm_i64_ty) intrinsic for that, indicating that for particular pointer let's call it %ptr we observed maximum possible offset at which there was reference by its type in a function. After InstCombine deleted the load operation, it could be restored in SLPVectorizer and we could restore chains of GEPs, Loads and Inserts in case we encounter phatom_mem intrinsic. Here is two part review: https://reviews.llvm.org/D37579 - InstCombine part. https://reviews.llvm.org/D37648 - SLP part. Also, there might be different approaches in describing deleted memory operations, for example, for my case: phantom_load(llvm_anyptr_ty, llvm_i64_ty). First parameter describes pointer and second parameter offset from pointer this loaded was deleted, for example. This two operations: %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 %ld1 = load double, double* %arrayidx1 could be represented in the IR with this one: "void phantom_load(%ptr, 1)" after removal. But, the approach that is already implemented in both reviews looks better to me since we don't need to add intrinsic for every removed operation in the IR. Also, while constructing such form in the IR we have to be careful since some pointer operations might be in loops and as the result we might end up construction an incorrect IR. So, I just avoid to notice any pointer operation if it is belong to a loop, except those where the the whole chain of operations pointer origin, GEP, Load, Shuffle operation are in the same loop and in the same basic block. Thanks, Dinar. Here is the thread for this issue regarding using metadata: http://lists.llvm.org/pipermail/llvm-dev/2017-July/115730.html
Interesting approach but how do you handle more complex offsets, e.g., when the pointer is part of an aggregate? Only one offset does not seem enough to handle generic cases. -----Original Message----- From: Dinar Temirbulatov via llvm-dev [llvm-dev at lists.llvm.org] Received: Dienstag, 12 Sep. 2017, 9:57 To: llvm-dev at lists.llvm.org [llvm-dev at lists.llvm.org] CC: Filipe Cabecinhas [me at filcab.net] Subject: [llvm-dev] RFC phantom memory intrinsic Hi, For PR21780 solution, I plan to add a new functionality to restore memory operations that was once deleted, in this particular case it is the load operations that were deleted by InstCombine, please note that once the load was removed there is no way to restore it back and that prevents us from vectorizing the shuffle operation. There are probably more similar issues where this approach could be applied. I added phatom_mem(llvm_anyptr_ty, llvm_i64_ty) intrinsic for that, indicating that for particular pointer let's call it %ptr we observed maximum possible offset at which there was reference by its type in a function. After InstCombine deleted the load operation, it could be restored in SLPVectorizer and we could restore chains of GEPs, Loads and Inserts in case we encounter phatom_mem intrinsic. Here is two part review: https://reviews.llvm.org/D37579 - InstCombine part. https://reviews.llvm.org/D37648 - SLP part. Also, there might be different approaches in describing deleted memory operations, for example, for my case: phantom_load(llvm_anyptr_ty, llvm_i64_ty). First parameter describes pointer and second parameter offset from pointer this loaded was deleted, for example. This two operations: %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 %ld1 = load double, double* %arrayidx1 could be represented in the IR with this one: "void phantom_load(%ptr, 1)" after removal. But, the approach that is already implemented in both reviews looks better to me since we don't need to add intrinsic for every removed operation in the IR. Also, while constructing such form in the IR we have to be careful since some pointer operations might be in loops and as the result we might end up construction an incorrect IR. So, I just avoid to notice any pointer operation if it is belong to a loop, except those where the the whole chain of operations pointer origin, GEP, Load, Shuffle operation are in the same loop and in the same basic block. Thanks, Dinar. Here is the thread for this issue regarding using metadata: http://lists.llvm.org/pipermail/llvm-dev/2017-July/115730.html _______________________________________________ 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/20170912/712b8bca/attachment.html>
Dinar Temirbulatov via llvm-dev
2017-Sep-13 03:54 UTC
[llvm-dev] RFC phantom memory intrinsic
Hi Michael,>Interesting approach but how do you handle more complex offsets, e.g., when the pointer is part of an aggregate? Only one offset does not seem enough to handle generic cases.Yes, correct, this a little bit changed example is not working. #include <x86intrin.h> __m256d vsht_d4_fold(const double* ptr, unsigned long long i) { __m256d foo = (__m256d){ ptr[i], ptr[i+1], ptr[i+2], ptr[i+3] }; return __builtin_shufflevector( foo, foo, 3, 3, 2, 2 ); } But with the aggregate case it is a new level of complexity, should we we care about? There might be some logic that probably would be mark as dead by InstCombine and we don't want to keep it. BTW: Looks like SLP could not recognize the case either : define <4 x double> @vsht_d4_fold(double* %ptr, i64 %i) local_unnamed_addr #0 { entry: %arrayidx = getelementptr inbounds double, double* %ptr, i64 %i %0 = load double, double* %arrayidx, align 8 %vecinit = insertelement <4 x double> undef, double %0, i32 0 %add = add i64 %i, 1 %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 %add %1 = load double, double* %arrayidx1, align 8 %vecinit2 = insertelement <4 x double> %vecinit, double %1, i32 1 %add3 = add i64 %i, 2 %arrayidx4 = getelementptr inbounds double, double* %ptr, i64 %add3 %2 = load double, double* %arrayidx4, align 8 %vecinit5 = insertelement <4 x double> %vecinit2, double %2, i32 2 %add6 = add i64 %i, 3 %arrayidx7 = getelementptr inbounds double, double* %ptr, i64 %add6 %3 = load double, double* %arrayidx7, align 8 %vecinit8 = insertelement <4 x double> %vecinit5, double %3, i32 3 %shuffle = shufflevector <4 x double> %vecinit8, <4 x double> %vecinit8, <4 x i32> <i32 3, i32 3, i32 2, i32 2> ret <4 x double> %shuffle } Thanks, Dinar. On Tue, Sep 12, 2017 at 8:26 PM, Haidl, Michael <michael.haidl at uni-muenster.de> wrote:> Interesting approach but how do you handle more complex offsets, e.g., when > the pointer is part of an aggregate? Only one offset does not seem enough to > handle generic cases. > > -----Original Message----- > From: Dinar Temirbulatov via llvm-dev [llvm-dev at lists.llvm.org] > Received: Dienstag, 12 Sep. 2017, 9:57 > To: llvm-dev at lists.llvm.org [llvm-dev at lists.llvm.org] > CC: Filipe Cabecinhas [me at filcab.net] > Subject: [llvm-dev] RFC phantom memory intrinsic > > Hi, > For PR21780 solution, I plan to add a new functionality to restore > memory operations that was once deleted, in this particular case it is > the load operations that were deleted by InstCombine, please note that > once the load was removed there is no way to restore it back and that > prevents us from vectorizing the shuffle operation. There are probably > more similar issues where this approach could be applied. > I added phatom_mem(llvm_anyptr_ty, llvm_i64_ty) intrinsic for that, > indicating that for particular pointer let's call it %ptr we observed > maximum possible offset at which there was reference by its type in a > function. After InstCombine deleted the load operation, it could be > restored in SLPVectorizer and we could restore chains of GEPs, Loads > and Inserts in case we encounter phatom_mem intrinsic. > > Here is two part review: > https://reviews.llvm.org/D37579 - InstCombine part. > https://reviews.llvm.org/D37648 - SLP part. > > Also, there might be different approaches in describing deleted memory > operations, for example, for my case: phantom_load(llvm_anyptr_ty, > llvm_i64_ty). First parameter describes pointer and second parameter > offset from pointer this loaded was deleted, for example. This two > operations: > > %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 > %ld1 = load double, double* %arrayidx1 > > could be represented in the IR with this one: "void phantom_load(%ptr, > 1)" after removal. But, the approach that is already implemented in > both reviews looks better to me since we don't need to add intrinsic > for every removed operation in the IR. Also, while constructing such > form in the IR we have to be careful since some pointer operations > might be in loops and as the result we might end up construction an > incorrect IR. So, I just avoid to notice any pointer operation if it > is belong to a loop, except those where the the whole chain of > operations pointer origin, GEP, Load, Shuffle operation are in the > same loop and in the same basic block. > Thanks, Dinar. > > Here is the thread for this issue regarding using metadata: > http://lists.llvm.org/pipermail/llvm-dev/2017-July/115730.html > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
In many cases, we can resolve such cases via a speculative load. I assume you've reviewed the case at hand to ensure we can't speculative insert a wider load in the case you need? That doesn't work for the store case, but if you just care about loads... Philip On 09/12/2017 12:54 AM, Dinar Temirbulatov via llvm-dev wrote:> Hi, > For PR21780 solution, I plan to add a new functionality to restore > memory operations that was once deleted, in this particular case it is > the load operations that were deleted by InstCombine, please note that > once the load was removed there is no way to restore it back and that > prevents us from vectorizing the shuffle operation. There are probably > more similar issues where this approach could be applied. > I added phatom_mem(llvm_anyptr_ty, llvm_i64_ty) intrinsic for that, > indicating that for particular pointer let's call it %ptr we observed > maximum possible offset at which there was reference by its type in a > function. After InstCombine deleted the load operation, it could be > restored in SLPVectorizer and we could restore chains of GEPs, Loads > and Inserts in case we encounter phatom_mem intrinsic. > > Here is two part review: > https://reviews.llvm.org/D37579 - InstCombine part. > https://reviews.llvm.org/D37648 - SLP part. > > Also, there might be different approaches in describing deleted memory > operations, for example, for my case: phantom_load(llvm_anyptr_ty, > llvm_i64_ty). First parameter describes pointer and second parameter > offset from pointer this loaded was deleted, for example. This two > operations: > > %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1 > %ld1 = load double, double* %arrayidx1 > > could be represented in the IR with this one: "void phantom_load(%ptr, > 1)" after removal. But, the approach that is already implemented in > both reviews looks better to me since we don't need to add intrinsic > for every removed operation in the IR. Also, while constructing such > form in the IR we have to be careful since some pointer operations > might be in loops and as the result we might end up construction an > incorrect IR. So, I just avoid to notice any pointer operation if it > is belong to a loop, except those where the the whole chain of > operations pointer origin, GEP, Load, Shuffle operation are in the > same loop and in the same basic block. > Thanks, Dinar. > > Here is the thread for this issue regarding using metadata: > http://lists.llvm.org/pipermail/llvm-dev/2017-July/115730.html > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev