This is an archive of the discontinued LLVM Phabricator instance.

[polly] [ScopInfo] Don't use isl_val_get_num_si.
ClosedPublic

Authored by efriedma on Jan 16 2018, 1:46 PM.

Details

Summary

isl_val_get_num_si crashes on overflow, so don't use it on arbitrary integers. Instead, convert to an APInt and explicitly check for overflow.

Testcase only crashes on platforms where long is 32 bits because of the signature of isl_val_get_num_si; not sure if it's possible to write a testcase which crashes if long is 64 bits.

There are a few other places in polly which use isl_val_get_num_si; they probably need to be fixed as well. I don't think polly uses any of the other "long" isl APIs in an unsafe manner.

Diff Detail

Repository
rL LLVM

Event Timeline

efriedma created this revision.Jan 16 2018, 1:46 PM
Meinersbur added inline comments.Jan 16 2018, 1:51 PM
lib/Analysis/ScopInfo.cpp
3429 ↗(On Diff #130022)

Why not making ValInt (and the Int vector etc) a long?

Meinersbur added inline comments.Jan 16 2018, 2:01 PM
lib/Analysis/ScopInfo.cpp
3431 ↗(On Diff #130022)

There might be a misconception here: isl_val_is_int only returns false for fractions. We don't use rational polyhedral sets, so the branch is always taken, even if Val exceeds any range.

3439 ↗(On Diff #130022)

Does it make sense to fall-through with ValInt = 1 if the value exceeds the range? It seems to be intended, but I don't see what the effect is.

efriedma added inline comments.Jan 16 2018, 2:20 PM
lib/Analysis/ScopInfo.cpp
3429 ↗(On Diff #130022)

I don't see how making ValInt a 64-bit integer is any better than making it a 32-bit integer. At least, it's orthogonal to the crash fix.

3431 ↗(On Diff #130022)

It looks like isl_aff_get_denominator_val always returns either a nan or an int. No idea if nan can actually show up here.

3439 ↗(On Diff #130022)

The effect is that it eventually fails the transform, because we set CanFold to false.

Meinersbur accepted this revision.Jan 16 2018, 2:36 PM

LGTM.

Fallback value can be discussed separately, it also exists in the current codebase.

lib/Analysis/ScopInfo.cpp
3429 ↗(On Diff #130022)

OK, from your post on isl-dev, I was under the impression that this was a platform issue.

3432–3434 ↗(On Diff #130022)

One could check whether it fits an int more directly (without requiring APInt) using isl_val_cmp_si (twice: for INT_MIN and INT_MAX) or isl_val_n_abs_num_chunks(Val) < 32.

3439 ↗(On Diff #130022)

Only Int[0] is checked on line 3473, but the fallback can happen on any dimension. Am I missing something?

This revision is now accepted and ready to land.Jan 16 2018, 2:36 PM
efriedma added inline comments.Jan 16 2018, 2:51 PM
lib/Analysis/ScopInfo.cpp
3429 ↗(On Diff #130022)

The crash happens inside isl_val_get_num_si (it has an explicit call to "die()" if the value doesn't fit into a "long").

Thinking about it a bit more, I guess the implicit truncation in the expression "ValInt = isl_val_get_num_si(Val);" could cause polly to miscompile a loop? I'm not sure how to construct a testcase, though.

3439 ↗(On Diff #130022)

We check the other dimensions in the loop immediately after that.

This revision was automatically updated to reflect the committed changes.