This is an archive of the discontinued LLVM Phabricator instance.

[IR] Value::getPointerAlignment(): handle pointer constants
ClosedPublic

Authored by lebedev.ri on Jan 21 2020, 12:26 PM.

Details

Summary

New @test13 in Attributor/align.ll is the main motivation - null pointer
really does not limit our alignment knowledge, in fact it is fully aligned
since it has no bits set.

Here we don't special-case null pointer because it is somewhat controversial
to add one more place where we enforce that null pointer is zero,
but instead we do the more general thing of trying to perform constant-fold
of pointer constant to an integer, and perform alignment inferrment on that.

Diff Detail

Event Timeline

lebedev.ri created this revision.Jan 21 2020, 12:26 PM
jdoerfert accepted this revision.Jan 21 2020, 2:00 PM

LGTM with one suggestion

llvm/test/Transforms/Attributor/nonnull.ll
531

I was about to ask for a test with a non-null constant when I saw this. Maybe we should have one more prominently as @test13 above?

This revision is now accepted and ready to land.Jan 21 2020, 2:00 PM
lebedev.ri marked 2 inline comments as done.Jan 21 2020, 2:04 PM
lebedev.ri added inline comments.
llvm/test/Transforms/Attributor/nonnull.ll
531

Will add one explicit one.

This revision was automatically updated to reflect the committed changes.
lebedev.ri marked an inline comment as done.
mlychkov added a subscriber: mlychkov.EditedFeb 6 2020, 4:54 AM

Hi @lebedev.ri,
We faced some side effect of this patch. During processing of getelementptr instruction it may create new user of this instruction. However this user is not actually used by generated code.
As example, during processing of the following instruction

%3 = load %struct_t*, %struct_t** getelementptr inbounds ([8 x %struct_t*], [8 x %struct_t*]* @globvar, i64 0, i64 0), align 8, !tbaa !16

the following constant expresion is created

i64 ptrtoint ([8 x %struct_t*]* @globvar to i64)

Later in one of our passes we change all users of @globvar variable and this extra user is unexpected.

Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

...
Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

Or is there a way to perform this computation without const_cast?

...
Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

Or is there a way to perform this computation without const_cast?

The problem is ConstantExpr::getPtrToInt. Do we striclty need that?

...
Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

Or is there a way to perform this computation without const_cast?

The problem is ConstantExpr::getPtrToInt. Do we striclty need that?

That is the workhorse here, we can't get around using it.

Without seeing the code where this is causing trouble i'm somewhat unsure
on how this is a problem, or how to test that the fix would actually fix it.
Perhaps, after computing TrailingZeros, we need to explicitly DCE CstInt?

...
Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

Or is there a way to perform this computation without const_cast?

The problem is ConstantExpr::getPtrToInt. Do we striclty need that?

That is the workhorse here, we can't get around using it.

Without seeing the code where this is causing trouble i'm somewhat unsure
on how this is a problem, or how to test that the fix would actually fix it.
Perhaps, after computing TrailingZeros, we need to explicitly DCE CstInt?

That'll probably work as well. If CstInt has 0 users it can be removed.

...
Is this alignment accounting intended to be used for getelementptr instructions too?
If yes then may we cleanup extra user after we get TrailingZeros value?

Or is there a way to perform this computation without const_cast?

The problem is ConstantExpr::getPtrToInt. Do we striclty need that?

That is the workhorse here, we can't get around using it.

Without seeing the code where this is causing trouble i'm somewhat unsure
on how this is a problem, or how to test that the fix would actually fix it.
Perhaps, after computing TrailingZeros, we need to explicitly DCE CstInt?

That'll probably work as well. If CstInt has 0 users it can be removed.

Do we have an established precedent on this kind of issues?
I don't recall ever seeing such a problem before,
nor do i recall seeing manual cleaning up of tmp constantexprs.
I'm mainly wondering whether we actually have such guarantees that this violated (should not create new users)?

nikic added a comment.Feb 8 2020, 12:39 PM

Sounds pretty odd to me too. From a quick grep, there's only a handful of destroyConstant() uses outside GlobalOpt, and those tend to deal with BlockAddress only (which is somewhat particular about uses).