This is an archive of the discontinued LLVM Phabricator instance.

Detect more min/max patterns in ScalarEvolution
AbandonedPublic

Authored by mreisinger on Jun 25 2016, 8:31 AM.

Details

Summary

The exact patterns, that this patch will enable to be detected, are the following:

a+1 >s b ? a+x : b+x -> smax(a, b)+x
a+1 >s b ? b+x : a+x -> smin(a, b)+x
a+1 >u b ? a+x : b+x -> umax(a, b)+x
a+1 >u b ? b+x : a+x -> umin(a, b)+x

Computations of this form are currently emitted, for example, by the LLVM code generator of the Julia language. This change also resolves the following bug that has been reported for Polly: https://llvm.org/bugs/show_bug.cgi?id=28126. Special thanks go to Michael Kruse for his detailed hints on how to address this problem.

Diff Detail

Event Timeline

mreisinger updated this revision to Diff 61890.Jun 25 2016, 8:31 AM
mreisinger retitled this revision from to Detect more min/max patterns in ScalarEvolution.
mreisinger updated this object.
mreisinger added reviewers: grosser, Meinersbur.
mreisinger updated this object.EditedJun 25 2016, 8:41 AM

Unfortunately, these changes cause the function createNodeForSelectOrPHI to get quite long. Originally I tried to combine the added code with the existing pattern matching logic in the ICMP_SGE and ICMP_UGE case branches. But in my opinion this caused the code to get too unclear, so I decided to separate the logic. In case the provided test cases are too compact, I can also try to define more extensive ones. Also I was not sure where the existing pattern matching logic is tested, therefore, for now, I added a separate test file for this.

Thank you in advance for any kind of input on this!

sanjoy requested changes to this revision.Jun 25 2016, 12:10 PM
sanjoy added a reviewer: sanjoy.

I'm not sure if these are correct. What if a is INT_MAX in the signed case or -1 in the unsigned case?

This revision now requires changes to proceed.Jun 25 2016, 12:10 PM

Thank you for bringing this to my notice, I will address these issues and update the patch.

Meinersbur added inline comments.Jun 26 2016, 3:00 PM
lib/Analysis/ScalarEvolution.cpp
4251

This fall through doesn't work. The a <s (b+1) case is only correct with strict comparisons (ICMP_SLT), but the code below would also allow it with ICMP_SLE.

4292

same as above

Meinersbur edited edge metadata.Jun 26 2016, 3:06 PM

For less code duplication, you might extract out a function that takes as argument whether it's a strict comparison and whether it's signed/unsigned comparison.

Michael

Thank you for your comments Michael! However, regarding Sanjoy's concerns, I am unsure if it's really possible to change these patterns to be applicable in cases where the absence of a wraparound cannot be assured, like in the provided test cases. I hope not to overlook obvious opportunities for such a generalization. However, if it's indeed unattainable at the level of ScalarEvolution, this would at least unveil the necessity to handle this via canonicalization on the side of Julia's LLVM code generator. If true, I am sorry that this patch was needed to gain this insight.

Teaching the Julia complier to add nsw/nuw flags shouldn't be that difficult. One might also test first whether the register has its extreme value. However, this would replace a select with another select and probably not that useful.

mreisinger abandoned this revision.Jul 17 2016, 4:29 AM

Thank you for all the comments. I close this now, in favor of a different approach. The recent discussion on this can also be followed at https://groups.google.com/forum/#!topic/julia-dev/5io1KnEswqs